source: trunk/www/common/expression_builder.jsp @ 4916

Last change on this file since 4916 was 4916, checked in by Nicklas Nordborg, 13 years ago

References #1120: The dynamic part of BASE should keep track whether intensity data is in log space or not

Fixes for spot data listings and experiment explorer.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 16.3 KB
Line 
1<%-- $Id: expression_builder.jsp 4916 2009-04-30 09:32:26Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2006, 2007 Nicklas Nordborg
4
5  This file is part of BASE - BioArray Software Environment.
6  Available at http://base.thep.lu.se/
7
8  BASE is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12
13  BASE is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with BASE. If not, see <http://www.gnu.org/licenses/>.
20  ------------------------------------------------------------------
21
22  @author Nicklas
23  @version 2.0
24--%>
25<%@ page session="false"
26  import="net.sf.basedb.core.DbControl"
27  import="net.sf.basedb.core.SessionControl"
28  import="net.sf.basedb.core.Item"
29  import="net.sf.basedb.core.BioAssaySet"
30  import="net.sf.basedb.core.RawDataType"
31  import="net.sf.basedb.core.RawDataTypes"
32  import="net.sf.basedb.core.RawDataProperty"
33  import="net.sf.basedb.core.ExtendedProperty"
34  import="net.sf.basedb.core.ExtendedProperties"
35  import="net.sf.basedb.core.Formula"
36  import="net.sf.basedb.core.ReporterList"
37  import="net.sf.basedb.core.ItemQuery"
38  import="net.sf.basedb.core.Include"
39  import="net.sf.basedb.core.query.Orders"
40  import="net.sf.basedb.core.query.Hql"
41  import="net.sf.basedb.util.Enumeration"
42  import="net.sf.basedb.util.jep.Jep"
43  import="net.sf.basedb.clients.web.Base"
44  import="net.sf.basedb.util.Values"
45  import="net.sf.basedb.clients.web.util.HTML"
46  import="net.sf.basedb.clients.web.DynamicUtil"
47  import="net.sf.basedb.clients.web.taglib.table.TableColumn"
48  import="java.util.List"
49  import="java.util.LinkedList"
50%>
51<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
52<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
53<%
54  String title = request.getParameter("title");
55  String form = request.getParameter("form");
56  String textarea = request.getParameter("textarea");
57  String callback = request.getParameter("callback");
58  Formula.Type formulaType = Formula.Type.valueOf(request.getParameter("formulatype"));
59  RawDataType rawDataType = RawDataTypes.getRawDataType(request.getParameter("rawdatatype"));
60  int bioAssaySetId = Values.getInt(request.getParameter("bioassayset_id"), -1);
61  boolean restrictions = Values.getBoolean(request.getParameter("restrictions"));
62  int channels = Values.getInt(request.getParameter("channels"));
63  final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
64 
65  DbControl dc = sc.newDbControl();
66  try
67  {
68    BioAssaySet bas = bioAssaySetId == -1 ? null : BioAssaySet.getById(dc, bioAssaySetId);
69    int maxRawMappings = bas == null ? 1 : bas.getMaxRawMappingsForSpot();
70
71    List<TableColumn> spotProperties = new LinkedList<TableColumn>();
72    DynamicUtil.addSpotColumns(spotProperties, dc, channels, null);
73    List<TableColumn> rawProperties = new LinkedList<TableColumn>();
74    if (rawDataType != null)
75    {
76      DynamicUtil.addFormulaColumns(spotProperties, dc, rawDataType, Formula.Type.COLUMN_EXPRESSION, "", "", maxRawMappings == 1);
77      if (bas != null) DynamicUtil.addExtraColumns(spotProperties, dc, bas, "", "", "[Xtra] ");
78      if (maxRawMappings == 1) DynamicUtil.addRawDataColumns(rawProperties, dc, rawDataType, "", "", "");
79    }
80    List<TableColumn> reporterProperties = new LinkedList<TableColumn>();
81    DynamicUtil.addReporterColumns(reporterProperties, dc, "", "", "");
82   
83    ItemQuery<ReporterList> reporterListQuery = ReporterList.getQuery();
84    reporterListQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
85    reporterListQuery.order(Orders.asc(Hql.property("name")));
86    List<ReporterList> reporterLists = reporterListQuery.list(dc);
87   
88  %>
89  <base:page type="popup" title="<%=title%>">
90  <base:head scripts="table.js" styles="toolbar.css">
91    <script language="JavaScript">
92    function getText()
93    {
94      document.forms['expression'].expression.value = window.opener.document.forms['<%=form%>'].elements['<%=textarea%>'].value;
95    }
96    function setExpressionAndClose()
97    {
98      var value = document.forms['expression'].expression.value;
99      <%
100      if (callback != null)
101      {
102        StringBuilder sb = new StringBuilder();
103        sb.append("window.opener.");
104        sb.append(callback).append("(");
105        if (form != null) sb.append("'").append(form).append("',");
106        if (textarea != null) sb.append("'").append(textarea).append("',");
107        sb.append("value)");
108        %>
109        <%=sb.toString()%>
110        <%
111      }
112      else
113      {
114        %>
115        var textElement = window.opener.document.forms['<%=form%>'].elements['<%=textarea%>'];
116        if (textElement.type == 'text') value = value.replace(/\n/g, '');
117        textElement.value = value;
118        <%
119      }
120      %>
121      window.close();
122    }
123    function insertSelected(list, prefix, suffix)
124    {
125      var value = list[list.selectedIndex].value;
126      if (value != '')
127      {
128        if (prefix) value = prefix + value;
129        if (!suffix) suffix = '';
130        encloseSelection(value, suffix);
131      }
132      list.selectedIndex = 0;
133    }
134    function insertReporterListFunction()
135    {
136      var frm = document.forms['expression'];
137      var listFunction = frm.listFunction[frm.listFunction.selectedIndex].value;
138      var listId = frm.reporterList[frm.reporterList.selectedIndex].value;
139      encloseSelection(listFunction+'(' + listId + ')', '');
140      frm.reporterList.selectedIndex = 0;
141    }
142 
143    /*
144      Enclose the selected text with prefix and suffix. Code taken
145      from Trac: http://projects.edgewall.com/trac/
146    */
147    function encloseSelection(prefix, suffix)
148    {
149      var frm = document.forms['expression'];
150      var textarea = frm.expression;
151      textarea.focus();
152        var start, end, sel, scrollPos, subst;
153        if (typeof(document["selection"]) != "undefined")
154        {
155          sel = document.selection.createRange().text;
156        }
157        else if (typeof(textarea["setSelectionRange"]) != "undefined")
158        {
159          start = textarea.selectionStart;
160          end = textarea.selectionEnd;
161          scrollPos = textarea.scrollTop;
162          sel = textarea.value.substring(start, end);
163        }
164        if (sel.match(/ $/))
165        {
166          // exclude ending space char, if any
167            sel = sel.substring(0, sel.length - 1);
168            suffix = suffix + " ";
169        }
170        subst = prefix + sel + suffix;
171        if (typeof(document["selection"]) != "undefined")
172        {
173          var range = document.selection.createRange().text = subst;
174          textarea.caretPos -= suffix.length;
175        }
176        else if (typeof(textarea["setSelectionRange"]) != "undefined")
177        {
178          textarea.value = textarea.value.substring(0, start) + subst +
179                           textarea.value.substring(end);
180          if (sel)
181          {
182            textarea.setSelectionRange(start + subst.length, start + subst.length);
183          }
184          else
185          {
186            textarea.setSelectionRange(start + prefix.length, start + prefix.length);
187          }
188          textarea.scrollTop = scrollPos;
189        }
190      }
191   
192    var properties = new Array();
193    <%
194    for (TableColumn tc : rawProperties)
195    {
196      %>
197      properties['raw.<%=tc.getProperty()%>'] = 1;
198      <%
199    }
200    for (TableColumn tc : reporterProperties)
201    {
202      %>
203      properties['reporter.<%=tc.getProperty()%>'] = 1;
204      <%
205    }
206    %>
207     
208    function validateOnClick()
209    {
210      var frm = document.forms['expression'];
211      if (frm.expression.value != '')
212      {
213        var expression = frm.expression.value.replace('if(', 'jepIf(');
214        try
215        {
216          var result = eval(expression);
217          alert('The expressions seems to be ok.\nNote! This feature is experimental and may not be 100% correct.');
218        }
219        catch (er)
220        {
221          alert(er + '\nNote! This feature is experimental and may not be 100% correct.');
222        }
223      }
224    }
225   
226    function raw(property)
227    {
228      <%
229      if (maxRawMappings != 1)
230      {
231        %>
232        throw 'Cannot use function raw() for bioassayset that has multiple mappings to raw data';
233        <%
234      }
235      %>
236      var rdt = '<%=rawDataType == null ? "" : rawDataType.getId()%>';
237      if (!property) throw 'Property must be specified for function raw()';
238      if (rdt == '') throw 'Cannot use function raw(). No raw data type selected';
239      if (!properties['raw.'+property]) throw 'Property '+property+' not found for raw data type ' + rdt;
240      return Math.random() * 100;
241    }
242   
243    function mean(property)
244    {
245      var rdt = '<%=rawDataType == null ? "" : rawDataType.getId()%>';
246      if (!property) throw 'Property must be specified for function mean()';
247      if (rdt == '') throw 'Cannot use function mean(). No raw data type selected';
248      if (!properties['property.'+property]) throw 'Property '+property+' not found for raw data type ' + rdt;
249      return Math.random() * 100;
250    }
251 
252    function ch(channel)
253    {
254      checkChannel('ch()', channel);
255      return channel;
256    }
257    function rawCh(channel)
258    {
259      checkChannel('rawCh()', channel);
260      return channel;
261    }
262    function checkChannel(name, channel)
263    {
264      var type = '<%=formulaType.name()%>';
265      if (type == '<%=Formula.Type.INTENSITY_EXPRESSION.name()%>')
266      {
267        // Channel function not available
268        throw 'Function ' + name + ' is not available for ' + type;
269      }
270      var channels = <%=channels%>;
271      if (!channel || channel <= 0 || channel > channels)
272      {
273        throw 'Invalid channel: ' + channel + '; must be between 1 and '+ channels;
274      }
275    }
276
277
278   
279    function pos()
280    {
281      return Math.random() * 100;
282    }
283    function rep(property)
284    {
285      if (!property) throw 'Property must be specified for function rep()';
286      if (!properties['reporter.'+property]) throw 'Property '+property+' not found for reporter';
287      return Math.random() * 100;
288    }
289   
290    function xtra(arg)
291    {
292      if (!arg) throw 'One argument is required for function xtra()';
293      return Math.random() * 100;
294    }
295   
296    function log(value)
297    {
298      return Math.log(value);
299    }
300    function log2(value)
301    {
302      return Math.log(value);
303    }
304    function ln(value)
305    {
306      return Math.log(value);
307    }
308    function sqrt(value)
309    {
310      return Math.sqrt(value);
311    }
312    function abs(value)
313    {
314      return Math.abs(value);
315    }
316    function exp(value)
317    {
318      return Math.exp(value);
319    }
320    function score(reporterListId)
321    {
322      return Math.random() * 100;
323    }
324    function jepIf(condition, ifTrue, ifFalse)
325    {
326      if (condition == undefined || ifTrue == undefined || ifFalse == undefined)
327      {
328        throw 'if() needs 3 arguments';
329      }
330      return condition ? ifTrue : ifFalse;
331    }
332    </script>
333  </base:head>
334  <base:body onload="getText()">
335 
336    <form name="expression" onsubmit="return false;">
337 
338        <h3 class="docked">Expression builder <base:help helpid="expressionbuilder" /></h3>
339       
340        <tbl:toolbar>
341          <tbl:label
342            style="width: 100px;"
343            title="Operators:"
344          />
345          <tbl:button 
346            title="AND"
347            tooltip="BOOLEAN AND: expr1 &amp;&amp; expr2"
348            onclick="encloseSelection(' &amp;&amp; ', '')"
349          />
350          <tbl:button 
351            title="OR"
352            tooltip="BOOLEAN OR: expr1 || expr2"
353            onclick="encloseSelection(' || ', '')"
354          />
355          <tbl:button 
356            title="NOT"
357            tooltip="BOOLEAN NOT: !expr1"
358            onclick="encloseSelection('!', '')"
359          />
360          <tbl:button 
361            title="=="
362            tooltip="EQUAL: expr1 == expr2"
363            onclick="encloseSelection(' == ', '')"
364          />
365          <tbl:button 
366            title="!="
367            tooltip="INEQUAL: expr1 != expr2"
368            onclick="encloseSelection(' != ', '')"
369          />
370          <tbl:button 
371            title="&lt;"
372            tooltip="LESS: expr1 &lt; expr2"
373            onclick="encloseSelection(' &lt; ', '')"
374          />
375          <tbl:button 
376            title="&lt;="
377            tooltip="LESS OR EQUAL: expr1 &lt;= expr2"
378            onclick="encloseSelection(' &lt;= ', '')"
379          />
380          <tbl:button 
381            title="&gt;="
382            tooltip="MORE OR EQUAL: expr1 &gt;= expr2"
383            onclick="encloseSelection(' &gt;= ', '')"
384            visible="<%=restrictions%>"
385          />
386          <tbl:button 
387            title="&gt;"
388            tooltip="MORE: expr1 &gt; expr2"
389            onclick="encloseSelection(' &gt; ', '')"
390          />
391          <tbl:button 
392            title="+"
393            tooltip="ADD: expr1 + expr2"
394            onclick="encloseSelection(' + ', '')"
395          />
396          <tbl:button 
397            title="-"
398            tooltip="SUBTRACT: expr1 - expr2"
399            onclick="encloseSelection(' - ', '')"
400          />
401          <tbl:button 
402            title="*"
403            tooltip="MULTIPLY: expr1 * expr2"
404            onclick="encloseSelection(' * ', '')"
405          />
406          <tbl:button 
407            title="/"
408            tooltip="DIVIDE: expr1 / expr2"
409            onclick="encloseSelection(' / ', '')"
410          />
411          <tbl:button 
412            title="( )"
413            tooltip="PARENTHESIS: (expr1)"
414            onclick="encloseSelection('(', ')')"
415          />
416        </tbl:toolbar>
417        <tbl:toolbar
418          style="border-top: 0px;"
419          >
420          <tbl:label
421            title="Functions:"
422            style="width: 100px;"
423          />
424          <%
425          Enumeration<String, String> functions = Jep.getFunctions();
426          for (int i = 0; i < functions.size(); ++i)
427          {
428            String function = functions.getKey(i);
429            %>
430            <tbl:button 
431              title="<%=function%>"
432              tooltip="<%=functions.getValue(i)%>"
433              onclick="<%="encloseSelection('" + function +"(', ')')"%>"
434            />
435            <%
436          }
437          %>
438          <tbl:label
439            title="Constants:"
440            style="width: 100px;"
441          />
442          <tbl:button 
443            title="null"
444            tooltip="The null (unknown) value"
445            onclick="<%="encloseSelection('', 'null')"%>"
446          />
447          <tbl:button 
448            title="pi"
449            tooltip="<%="The pi value: " + Math.PI %>"
450            onclick="<%="encloseSelection('', '"+Math.PI+"')"%>"
451          />
452          <tbl:button 
453            title="e"
454            tooltip="<%="The base of the natural logarithm: " + Math.E%>"
455            onclick="<%="encloseSelection('', '"+Math.E+"')"%>"
456          />
457        </tbl:toolbar>
458        <tbl:toolbar
459          style="border-top: 0px;">
460          <td class="label">Spot:
461            <select name="spot" onchange="insertSelected(this)" >
462            <option value="">- select -
463            <%
464            for (TableColumn tc : spotProperties)
465            {
466              if (tc.getJepExpression() != null)
467              {
468                %>
469                <option value="<%=tc.getJepExpression()%>" 
470                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
471                <%
472              }
473            }
474            %>
475            </select>   
476          </td>
477          <%
478          if (rawDataType != null && rawDataType.isStoredInDb() && rawProperties.size() > 0)
479          {
480            %>
481            <td class="label">Raw data:
482              <select name="rawdata" onchange="insertSelected(this)" >
483              <option value="">- select -
484              <%
485              for (TableColumn tc : rawProperties)
486              {
487                %>
488                <option value="<%=tc.getJepExpression()%>" 
489                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
490                <%
491              }
492              %>
493              </select>
494            </td>
495            <%
496          }
497          %>
498         
499          <td class="label">Reporter:
500            <select name="reporter" onchange="insertSelected(this)">
501            <option value="">- select -
502              <%
503              for (TableColumn tc : reporterProperties)
504              {
505                %>
506                <option value="<%=tc.getJepExpression()%>" 
507                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
508                <%
509              }
510              %>
511            </select>
512        </tbl:toolbar>
513        <tbl:toolbar
514          style="border-top: 0px;"
515          visible="<%=reporterLists.size() > 0%>">
516          <td class="label">
517            Reporter lists:
518           
519            <select name="listFunction" >
520            <option value="score">score
521            <%
522            if (restrictions)
523            {
524              %>
525              <option value="inList">in
526              <option value="notInList">not in
527              <%
528            }
529            %>
530            </select>
531           
532            <select name="reporterList" onchange="insertReporterListFunction()">
533            <option value="">- select -
534              <%
535              for (ReporterList list : reporterLists)
536              {
537                %>
538                <option value="<%=list.getId()%>" 
539                  title="<%=HTML.encodeTags(list.getDescription())%>"><%=HTML.encodeTags(list.getName())%>
540                <%
541              }
542              %>
543            </select>
544          </td>
545        </tbl:toolbar>
546        <br>
547        <b>Expression</b><br>
548        <textarea name="expression" rows="16" cols="80" wrap="soft" style="width: 100%;"></textarea>
549
550        <br><br>
551        <table align="center">
552        <tr>
553          <td width="33%"><base:button 
554            onclick="validateOnClick()" title="Validate&hellip;" 
555            image="validate_formula.gif"
556            tooltip="Validate the expression. EXPERIMENTAL!!" /></td>
557          <td width="33%"><base:button onclick="setExpressionAndClose()" title="Ok" /></td>
558          <td width="33%"><base:button onclick="window.close()" title="Cancel" /></td>
559         
560        </tr>
561        </table>
562 
563    </form>
564  </base:body>
565  </base:page>
566  <%
567  }
568finally
569{
570  if (dc != null) dc.close();
571}
572%> 
Note: See TracBrowser for help on using the repository browser.