source: trunk/www/views/experiments/explorer/view/view.jsp @ 5711

Last change on this file since 5711 was 5711, checked in by Nicklas Nordborg, 10 years ago

References #1618: Improve "Reporter search" performance in experiment explorer

Different implementation on "Reporter search" that uses the cached reporter ids and use a regular query against the Reporters table only. As a result, the "Create reporter list" function needed to fixed as it can no longer use the query. Instead it also uses the cached reporter ids.

Added filter condition for bioassays when loading the "Reporter view" page since it seems to be a lot quicker (see comment 4).

Fixed an issue with generating incorrect SQL when filtering on a reporter list. I think this broke as part of #903, but has gone unnoticed since then. A join to the reporter list table was missing due to no auto-join support in DynamicPositionQuery and DynamicReporterQuery. Auto-join support has now been added to those query implementations.

Everything is a lot quicker now on my development machine. I have 2.5M reporters in the reporter table and an experiment with 24M rows of spot data in 500 bioassays. So far no action seems to take more than a couple of seconds to complete.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 27.8 KB
Line 
1<%-- $Id: view.jsp 5711 2011-08-30 13:49:58Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2006 Johan Enell, Nicklas Nordborg
4  Copyright (C) 2007 Nicklas Nordborg
5
6  This file is part of BASE - BioArray Software Environment.
7  Available at http://base.thep.lu.se/
8
9  BASE is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License
11  as published by the Free Software Foundation; either version 3
12  of the License, or (at your option) any later version.
13
14  BASE is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with BASE. If not, see <http://www.gnu.org/licenses/>.
21  ------------------------------------------------------------------
22
23  @author Nicklas
24  @version 2.0
25--%>
26<%@ page pageEncoding="UTF-8" session="false"
27  import="net.sf.basedb.core.SessionControl"
28  import="net.sf.basedb.core.DbControl"
29  import="net.sf.basedb.core.Item"
30  import="net.sf.basedb.core.ItemContext"
31  import="net.sf.basedb.core.PropertyFilter"
32  import="net.sf.basedb.core.Include"
33  import="net.sf.basedb.core.BioAssaySet"
34  import="net.sf.basedb.core.BioAssay"
35  import="net.sf.basedb.core.Experiment"
36  import="net.sf.basedb.core.RawDataType"
37  import="net.sf.basedb.core.RawBioAssay"
38  import="net.sf.basedb.core.RawDataUtil"
39  import="net.sf.basedb.core.ExtendedProperties"
40  import="net.sf.basedb.core.ExtendedProperty"
41  import="net.sf.basedb.core.AnnotationType"
42  import="net.sf.basedb.core.Annotation"
43  import="net.sf.basedb.core.Formula"
44  import="net.sf.basedb.core.IntensityTransform"
45  import="net.sf.basedb.core.ItemQuery"
46  import="net.sf.basedb.core.ItemResultList"
47  import="net.sf.basedb.core.DynamicSpotQuery"
48  import="net.sf.basedb.core.DynamicResultIterator"
49  import="net.sf.basedb.core.VirtualColumn"
50  import="net.sf.basedb.core.Type"
51  import="net.sf.basedb.core.data.ReporterData"
52  import="net.sf.basedb.core.data.RawData"
53  import="net.sf.basedb.core.query.Restrictions"
54  import="net.sf.basedb.core.query.Expressions"
55  import="net.sf.basedb.core.query.Dynamic"
56  import="net.sf.basedb.core.query.Orders"
57  import="net.sf.basedb.core.query.Selects"
58  import="net.sf.basedb.core.query.Aggregations"
59  import="net.sf.basedb.core.query.Hql"
60  import="net.sf.basedb.core.query.JoinType"
61  import="net.sf.basedb.core.query.SqlResult"
62  import="net.sf.basedb.util.Values"
63  import="net.sf.basedb.clients.web.Base"
64  import="net.sf.basedb.clients.web.DynamicUtil"
65  import="net.sf.basedb.clients.web.ExperimentExplorer"
66  import="net.sf.basedb.clients.web.ExperimentExplorer.AnnotationSummary"
67  import="net.sf.basedb.clients.web.ExperimentExplorer.AnnotationGroup"
68  import="net.sf.basedb.clients.web.WebException"
69  import="net.sf.basedb.clients.web.util.HTML"
70  import="net.sf.basedb.util.formatter.Formatter"
71  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
72  import="net.sf.basedb.clients.web.formatter.SpotImageFormatter"
73  import="net.sf.basedb.clients.web.taglib.table.TableColumn"
74  import="java.util.Date"
75  import="java.util.List"
76  import="java.util.ArrayList"
77  import="java.util.LinkedList"
78  import="java.util.Collection"
79  import="java.util.Arrays"
80  import="java.util.Set"
81  import="java.util.Map"
82  import="java.util.HashMap"
83%>
84<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
85<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
86<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
87<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
88<%!
89  private static final Item itemType = Item.SPOTDATA;
90  private static final String defaultReporterColumns = "name,externalId,symbol,description";
91%>
92<%
93final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
94final String ID = sc.getId();
95final float scale = Base.getScale(sc);
96final String root = request.getContextPath();
97
98final int bioAssaySetId = Values.getInt(request.getParameter("bioassayset_id"));
99final DbControl dc = sc.newDbControl();
100DynamicResultIterator spotData = null;
101try
102{
103  Formatter<Date> dateFormatter = FormatterFactory.getDateTimeFormatter(sc);
104  String title = null;
105  final BioAssaySet bioAssaySet = BioAssaySet.getById(dc, bioAssaySetId);
106  final Experiment experiment = bioAssaySet.getExperiment();
107  final RawDataType rawDataType = experiment.getRawDataType();
108  final int channels = rawDataType.getChannels();
109  final boolean hasRatio = channels == 2;
110  final int maxRawMappings = bioAssaySet.getMaxRawMappingsForSpot();
111  final IntensityTransform transform = bioAssaySet.getIntensityTransform();
112 
113  final ExperimentExplorer explorer = ExperimentExplorer.getExplorer(bioAssaySet);
114  final ItemContext cc = explorer.getAndSetSpotContext(sc, pageContext);
115  final ItemContext reporterContext = explorer.getAndSetReporterContext(sc, null);
116  final String subContext = cc.getSubContext();
117 
118  List<TableColumn> columns = new LinkedList<TableColumn>();
119  DynamicUtil.addFormulaColumns(columns, dc, rawDataType, Formula.Type.COLUMN_EXPRESSION, 
120    transform, "frm.", "", maxRawMappings == 1);
121  DynamicUtil.addExtraColumns(columns, dc, bioAssaySet, "ev", "#", "[Xtra] ");
122  if (maxRawMappings == 1)
123  {
124    DynamicUtil.addRawDataColumns(columns, dc, rawDataType, "raw.", "$", "[Raw] ");
125    columns.add(new TableColumn("raw.spotimage", "$id", "raw('id')", Type.INT, 
126      "[Raw] Spotimage", "", "auto", false, false, false, null, 
127      new SpotImageFormatter(dc, rawDataType, root)));
128  }
129
130  final int matchingReporters = explorer.getMatchingReporters(dc);
131  int reporterIndex = explorer.getReporterIndex();
132  if (reporterIndex >= matchingReporters) reporterIndex = matchingReporters - 1;
133  final ReporterData reporter = matchingReporters == 0 ? 
134      null : explorer.getReporter(dc, reporterIndex);
135
136  final int matchingPositions = matchingReporters == 0 ? 
137      0 : explorer.getNumPositions(dc, reporterIndex);
138 
139  int positionIndex = explorer.getPositionIndex();
140  if (positionIndex >= matchingPositions) positionIndex = matchingPositions - 1;
141  final boolean isAveraging = positionIndex == ExperimentExplorer.SPOT_AVG;
142 
143  final List<AnnotationType> annotationTypes = explorer.getAnnotationTypes(dc, true);
144  final Set<Integer> tmp = explorer.getAnnotationTypeIds();
145  final Map<AnnotationType, AnnotationSummary> selectedAnnotationTypes = 
146    new HashMap<AnnotationType, AnnotationSummary>(tmp.size());
147  for (Integer atId : tmp)
148  {
149    try
150    {
151      selectedAnnotationTypes.put(AnnotationType.getById(dc, atId), null);
152    }
153    catch (Throwable t)
154    {}
155  }
156
157  DynamicUtil.SelectedInfo selected = DynamicUtil.getSelectedColumns(cc, columns, isAveraging);
158 
159  List<String> sortProperties = null;
160  if (isAveraging && cc.getSortProperty() != null)
161  {
162    // We must check that we are not sorting on a non-averagable property
163    sortProperties = new ArrayList<String>(Arrays.asList(cc.getSortProperty().split(",")));
164    for (TableColumn tc : columns)
165    {
166      if (!tc.isAveragable()) sortProperties.remove(tc.getProperty());
167    }
168    cc.setSortProperty(Values.getString(sortProperties, ",", true));
169  }
170 
171  if (matchingReporters > 0)
172  {
173    for (Map.Entry<AnnotationType, AnnotationSummary> entry : selectedAnnotationTypes.entrySet())
174    {
175      entry.setValue(explorer.getAnnotationSummary(dc, entry.getKey()));
176    }
177    try
178    {
179      DynamicSpotQuery spotQuery = explorer.getSpotQuery(dc, reporterIndex, positionIndex, selected.selectedColumns);
180      spotData = spotQuery.iterate(dc);
181    }
182    catch (Throwable t)
183    {
184      cc.setMessage(t.getMessage());
185      t.printStackTrace();
186    }
187  }
188  %>
189  <base:page title="<%=title%>">
190  <base:head scripts="table.js,tabcontrol.js" styles="table.css,toolbar.css,headertabcontrol.css,path.css,explorer.css">
191  <script language="JavaScript">
192    var submitPage = 'index.jsp';
193    var formId = 'spotdata';
194    function configureColumns()
195    {
196      Table.configureColumns('<%=ID%>', formId, '<%=itemType.name()%>', '<%=(String)cc.getObject("defaultColumns")%>', '<%=subContext%>');
197    }
198    function configureReporterColumns()
199    {
200      var frm = document.forms['reporter'];
201      frm.cmd.value = 'SetReporterColumns';
202      Table.configureColumns('<%=ID%>', 'reporter', '<%=itemType.name()%>', '<%=defaultReporterColumns%>', '<%=subContext%>', 'reporter-columns');
203    }
204    function presetOnChange()
205    {
206      Table.presetOnChange('<%=ID%>', formId, '<%=itemType.name()%>', '<%=(String)cc.getObject("defaultColumns")%>', '<%=subContext%>');
207    }
208    function validateReporterIndex()
209    {
210      var frm = document.forms['reporterIndex'];
211      var reporterIndex = parseInt(frm.newReporterIndex.value);
212      var maxIndex = <%=matchingReporters%>;
213      if (reporterIndex < 1 || reporterIndex > maxIndex)
214      {
215        alert('The reporter index must be between 1 and ' + maxIndex);
216        return false;
217      }
218      frm.cmd.value = 'SetReporterIndex';
219      Forms.createHidden(frm, 'reporterIndex', reporterIndex-1);
220      return true;
221    }
222    function validateSpotIndex()
223    {
224      var frm = document.forms['spotIndex'];
225      var spotIndex = parseInt(frm.newSpotIndex.value);
226      var maxIndex = <%=matchingPositions%>;
227      if (spotIndex < 1 || spotIndex > maxIndex)
228      {
229        alert('The spot index must be between 1 and ' + maxIndex);
230        return false;
231      }
232      frm.cmd.value = 'SetSpotIndex';
233      Forms.createHidden(frm, 'spotIndex', spotIndex-1);
234      return true;
235    }
236    function annotationTypeOnChange()
237    {
238      var frm = document.forms['explorer'];
239      frm.cmd.value = 'SetAnnotationType';
240      frm.submit();
241    }
242    function viewSearch()
243    {
244      location.href = '../search/index.jsp?ID=<%=ID%>&bioassayset_id=<%=bioAssaySetId%>';
245    }
246    function switchTab(tabControlId, tabId)
247    {
248      if (tabId == 'search')
249      {
250        viewSearch();
251      }
252      else
253      {
254        TabControl.setActiveTab(tabControlId, tabId);
255      }
256    }
257    function assayPlot()
258    {
259      var url = 'plotter.jsp?ID=<%=ID%>&type=assay';
260      url += '&bioAssaySetId=<%=bioAssaySetId%>';
261      url += '&reporterIndex=<%=reporterIndex%>';
262      url += '&positionIndex=<%=positionIndex%>';
263      Main.openPopup(url, 'AssayPlot', 1100, 700);
264    }
265    function annotationPlot(annotationType)
266    {
267      var url = 'plotter.jsp?ID=<%=ID%>&type=annotation';
268      url += '&bioAssaySetId=<%=bioAssaySetId%>';
269      url += '&reporterIndex=<%=reporterIndex%>';
270      url += '&positionIndex=<%=positionIndex%>';
271      url += '&annotationTypeId=' + annotationType;
272      Main.openPopup(url, 'AnnotationPlot', 1100, 700);
273    }
274  </script>
275  </base:head>
276  <base:body>
277    <p>
278    <p:path>
279      <p:pathelement title="Experiments" href="<%="../../index.jsp?ID="+ID%>" />
280      <p:pathelement title="<%=HTML.encodeTags(experiment.getName())%>" 
281        href="<%="../../bioassaysets/index.jsp?ID="+ID+"&experiment_id="+experiment.getId()%>" />
282      <p:pathelement title="<%=HTML.encodeTags(bioAssaySet.getName())%>" 
283        href="<%="../../bioassaysets/index.jsp?ID="+ID+"&cmd=ViewItem&item_id="+bioAssaySetId%>" />
284      <p:pathelement title="Explorer" />
285    </p:path>
286   
287    <t:tabcontrol id="explorer" switch="switchTab" remember="false" active="view">
288    <t:tab id="search" title="Reporter search" />
289   
290    <t:tab id="view" title="Reporter view">
291    <div class="boxed">
292   
293    <%
294    Collection<PropertyFilter> filters = reporterContext.getPropertyFilters();
295    String filter = filters != null && filters.size() > 0 ? 
296      "(" + Values.getString(filters, ") AND (", true).replaceAll("@|�", "") + ")" : "- none -";
297    %>
298    <table class="form">
299    <tr>
300      <td class="prompt">Filter</td>
301      <td>
302      <%=HTML.encodeTags(filter)%>
303      </td>
304    </tr>
305    </table>
306   
307   
308    <%
309    if (reporter != null)
310    {
311      %>
312      <form name="reporterIndex" action="index.jsp" method="post">
313      <input type="hidden" name="ID" value="<%=ID%>">
314      <input type="hidden" name="bioassayset_id" value="<%=bioAssaySetId%>">
315      <input type="hidden" name="cmd" value="SetReporterIndex">
316      <h4 class="docked">Current reporter
317            <input name="newReporterIndex" type="text" class="text" value="<%=reporterIndex+1%>" 
318        onkeypress="return Numbers.integerOnly(event, true, validateReporterIndex)"
319        size="6" maxlength="8" title="Enter a number between 1 and <%=matchingReporters%>">
320      of <%=matchingReporters %>
321      <%
322      if (reporterIndex == 0 || matchingReporters == 0)
323      {
324        %>
325        <base:icon image="first_gray.gif" />
326        <base:icon image="previous_gray.gif" />
327        <%
328      }
329      else
330      {
331        %>
332        <a href="index.jsp?ID=<%=ID%>&cmd=SetReporterIndex&bioassayset_id=<%=bioAssaySetId%>&reporterIndex=0"
333          title="Go the first reporter"><base:icon image="first.gif" /></a>
334        <a href="index.jsp?ID=<%=ID%>&cmd=SetReporterIndex&bioassayset_id=<%=bioAssaySetId%>&reporterIndex=<%=reporterIndex-1%>"
335          title="Go the previous reporter"><base:icon image="previous.gif" /></a>
336        <%
337      }
338      %>
339      &nbsp;&nbsp;
340      <%
341      if (reporterIndex == matchingReporters - 1 || matchingReporters == 0)
342      {
343        %>
344        <base:icon image="next_gray.gif" />
345        <base:icon image="last_gray.gif" />
346        <%
347      }
348      else
349      {
350        %>
351        <a href="index.jsp?ID=<%=ID%>&cmd=SetReporterIndex&bioassayset_id=<%=bioAssaySetId%>&reporterIndex=<%=reporterIndex+1%>"
352          title="Go the next reporter"><base:icon image="next.gif" /></a>
353        <a href="index.jsp?ID=<%=ID%>&cmd=SetReporterIndex&bioassayset_id=<%=bioAssaySetId%>&reporterIndex=<%=matchingReporters-1%>"
354          title="Go the last reporter"><base:icon image="last.gif" /></a>
355        <%
356      }
357      %>
358      </h4>
359      </form>
360     
361      <tbl:toolbar>
362        <tbl:button 
363          image="columns.gif" 
364          onclick="configureReporterColumns()" 
365          title="Columns&hellip;" 
366          tooltip="Show, hide and re-order reporter columns" 
367        />
368      </tbl:toolbar>
369   
370    <div class="boxedbottom">
371    <tbl:table 
372      id="reporter" 
373      clazz="form" 
374      columns="<%=Values.getString(cc.getSetting("reporter-columns"), defaultReporterColumns)%>"
375      action="index.jsp"
376      sc="<%=sc%>"
377      item="<%=itemType%>"
378      subcontext="<%=subContext%>"
379      >
380      <tbl:hidden 
381        name="bioassayset_id" 
382        value="<%=String.valueOf(bioAssaySetId)%>" 
383      />
384      <tbl:columndef id="name" title="Name" show="always" clazz="prompt"/>
385      <tbl:columndef id="externalId" title="External ID" clazz="prompt"/>
386      <tbl:columndef id="symbol" title="Gene symbol" clazz="prompt"/>
387      <tbl:columndef id="lastUpdate" title="Last update" clazz="prompt"/>
388      <tbl:columndef id="type" title="Type" clazz="prompt"/>
389      <tbl:columndef id="description" title="Description" clazz="prompt"/>
390      <%
391      List<ExtendedProperty> reporterProperties = ExtendedProperties.getProperties("ReporterData");
392      if (reporterProperties != null)
393      {
394        for (ExtendedProperty ep : reporterProperties)
395        {
396          String name = ep.getName();
397          Formatter formatter = FormatterFactory.getExtendedPropertyFormatter(sc, ep);
398          %>
399          <tbl:columndef 
400            id="<%=ep.getName()%>" 
401            title="<%=HTML.encodeTags(ep.getTitle())%>" 
402            clazz="prompt" 
403            formatter="<%=formatter%>"
404          />
405          <%
406        }
407      }
408      %>
409      <tbl:form width="2">
410        <tbl:cell column="name"><%=Base.getLink(ID, reporter.getName(), Item.REPORTER, reporter.getId(), true)%></tbl:cell>
411        <tbl:cell column="externalId"><%=HTML.encodeTags(reporter.getExternalId())%></tbl:cell>
412        <tbl:cell column="symbol"><%=HTML.encodeTags(reporter.getSymbol())%></tbl:cell>
413        <tbl:cell column="lastUpdate"><%=dateFormatter.format(reporter.getLastUpdate())%></tbl:cell>
414        <tbl:cell column="type"><base:propertyvalue dbcontrol="<%=dc%>" item="<%=reporter%>" property="reporterType" /></tbl:cell>
415        <tbl:cell column="description"><%=HTML.niceFormat(reporter.getDescription())%></tbl:cell>
416        <%
417        if (reporterProperties != null)
418        {
419          for (ExtendedProperty ep : reporterProperties)
420          {
421            String name = ep.getName();
422            Formatter formatter = FormatterFactory.getExtendedPropertyFormatter(sc, ep);
423            %>
424            <tbl:cell column="<%=ep.getName()%>"><tbl:cellvalue value="<%=reporter.getExtended(name)%>" /></tbl:cell>
425            <%
426          }
427        }
428        %>
429      </tbl:form>
430    </tbl:table>
431    </div>
432    <%
433    }
434    else
435    {
436      %>
437      No reporters found.
438      <%
439    }
440    %>
441   
442    <base:section
443      id="annotation"
444      title="<%="Annotation summary (" + selectedAnnotationTypes.size() + " selected)"%>"
445      context="<%=cc%>"
446      >
447      <form name="annotationSummary" action="index.jsp" method="POST" onsubmit="return false;">
448      <input type="hidden" name="ID" value="<%=ID%>">
449      <input type="hidden" name="bioassayset_id" value="<%=bioAssaySetId%>">
450      <input type="hidden" name="cmd" value="SetAnnotationType">
451        <table border="0" cellspacing="0" cellpadding="0"><tr><td>
452        <div class="multiselect">
453          <input type="text" class="text" size="40" name="display:annotationTypes"
454            title="Click to select experimental factor"><img 
455            class="smartimage" src="../../../../images/pull_down.gif" 
456            onclick="MultiOptions.activateAndDisplay('annotationSummary','display:annotationTypes')"></div>
457          <input type="hidden" name="annotationtype_id" value="">
458          </td></tr></table>
459        <%
460        if (selectedAnnotationTypes.size() > 0)
461        {
462          for (Map.Entry<AnnotationType, AnnotationSummary> entry : selectedAnnotationTypes.entrySet())
463          {
464            AnnotationType at = entry.getKey();
465            AnnotationSummary summary = entry.getValue();
466            %>
467            <table border="0" cellspacing="0" cellpadding="2" class="annotationsummary">
468            <tr>
469              <td class="summaryheader"><%=Base.getLinkedName(ID, at, false, true)%></td>
470              <td class="summaryheader"><base:icon
471                image="plotter.gif"
472                onclick="<%="annotationPlot(" + at.getId() + ")"%>"
473                tooltip="Box plot for selected spot data per annotation group"
474              /></td>
475              <%
476              for (AnnotationGroup ag : summary.getAnnotationGroups())
477              {
478                %>
479                <td class="groupheader" style="background: <%=ag.getColor()%>;" width="50px">
480                <%=ag.getTitle()%>
481                </td>
482                <%
483              }
484              %>
485              </tr>
486              <%
487              for (int ch = 1; ch <= channels; ++ch)
488              {
489                %>
490                <tr>
491                <td colspan="2">Mean ch <%=ch%> int.</td>
492                <%
493                for (AnnotationGroup ag : summary.getAnnotationGroups())
494                {
495                  %>
496                  <td class="value" style="background: <%=ag.getColor()%>;"
497                    id="mean.<%=at.getId()%>.<%=ag.getId()%>.ch<%=ch%>"></td>
498                  <%
499                }
500                %>
501                </tr>
502                <%
503              }
504              if (hasRatio)
505              {
506                %>
507                <tr>
508                <td colspan="2" title="The geometric mean of the ratios">G. mean ratio</td>
509                <%
510                for (AnnotationGroup ag : summary.getAnnotationGroups())
511                {
512                  %>
513                  <td class="value" style="background: <%=ag.getColor()%>;"
514                    id="gmean.<%=at.getId()%>.<%=ag.getId()%>"></td>
515                  <%
516                }
517                %>
518                </tr>
519                <tr>
520                <td colspan="2" title="Standard deviation of log2 ratios">log2ratio SD</td>
521                <%
522                for (AnnotationGroup ag : summary.getAnnotationGroups())
523                {
524                  %>
525                  <td class="value" style="background: <%=ag.getColor()%>;"
526                    id="sd.<%=at.getId()%>.<%=ag.getId()%>"></td>
527                  <%
528                }
529                %>
530                </tr>
531                <%
532              }
533              %>
534              <tr>
535              <td colspan="2" title="The number of spots falling in this group">Count</td>
536              <%
537              for (AnnotationGroup ag : summary.getAnnotationGroups())
538              {
539                %>
540                <td class="value" style="background: <%=ag.getColor()%>;"
541                  id="count.<%=at.getId()%>.<%=ag.getId()%>"></td>
542                <%
543              }
544              %>
545              </tr>
546            </table>
547            <%
548          }
549        }
550        %>
551        </form>
552    </base:section>
553
554    <form name="spotIndex" action="index.jsp" method="post">
555    <input type="hidden" name="ID" value="<%=ID%>">
556    <input type="hidden" name="bioassayset_id" value="<%=bioAssaySetId%>">
557    <input type="hidden" name="cmd" value="SetSpotIndex">
558   
559      <h4 class="docked">Current spot
560      <input name="newSpotIndex" type="text" class="text" value="<%=positionIndex == -1 ? "all" : positionIndex == -2 ? "avg" : String.valueOf(positionIndex+1)%>" 
561        onkeypress="return Numbers.integerOnly(event, true, validateSpotIndex)"
562        size="6" maxlength="8" title="Enter a number between 1 and <%=matchingPositions%>">
563        of <%=matchingPositions%>
564     
565        <%
566        if (positionIndex == 0)
567        {
568          %>
569          <base:icon image="first_gray.gif" />
570          <%
571        }
572        else
573        {
574          %>
575          <a href="index.jsp?ID=<%=ID%>&cmd=SetSpotIndex&bioassayset_id=<%=bioAssaySetId%>&spotIndex=0"
576            title="Go the first position"><base:icon image="first.gif" /></a>
577          <%
578        }
579        if (positionIndex <= 0)
580        {
581          %>
582          <base:icon image="previous_gray.gif" />
583          <%
584        }
585        else
586        {
587          %>
588          <a href="index.jsp?ID=<%=ID%>&cmd=SetSpotIndex&bioassayset_id=<%=bioAssaySetId%>&spotIndex=<%=positionIndex-1%>"
589            title="Go the previous position"><base:icon image="previous.gif" /></a>
590          <%
591        }
592        %>
593        &nbsp;&nbsp;
594        <%
595        if (positionIndex == matchingPositions - 1 || positionIndex < 0)
596        {
597          %>
598          <base:icon image="next_gray.gif" />
599          <%
600        }
601        else
602        {
603          %>
604          <a href="index.jsp?ID=<%=ID%>&cmd=SetSpotIndex&bioassayset_id=<%=bioAssaySetId%>&spotIndex=<%=positionIndex+1%>"
605            title="Go the next position"><base:icon image="next.gif" /></a>
606          <%
607        }
608        if (positionIndex == matchingPositions - 1)
609        {
610          %>
611          <base:icon image="last_gray.gif" />
612          <%
613        }
614        else
615        {
616          %>
617          <a href="index.jsp?ID=<%=ID%>&cmd=SetSpotIndex&bioassayset_id=<%=bioAssaySetId%>&spotIndex=<%=matchingPositions-1%>"
618            title="Go the last position"><base:icon image="last.gif" /></a>
619          <%
620        }
621        %>
622        [ <a href="index.jsp?ID=<%=ID%>&cmd=SetSpotIndex&bioassayset_id=<%=bioAssaySetId%>&spotIndex=-1"
623          title="Show all positions">all</a>
624        | <a href="index.jsp?ID=<%=ID%>&cmd=SetSpotIndex&bioassayset_id=<%=bioAssaySetId%>&spotIndex=-2"
625          title="Calculate average values for each bioassay">avg</a>
626        ]
627        </h4>
628     
629      </form>
630    <%
631    if (cc.getMessage() != null)
632    {
633      %>
634      <div class="error"><%=cc.getMessage()%></div>
635      <%
636      cc.setMessage(null);
637    }
638    %>
639   
640    <%
641    if (spotData != null)
642    {
643      Formatter<Number> numberFormatter = FormatterFactory.getNumberFormatter(sc);
644      %>
645
646    <tbl:table 
647      id="spotdata" 
648      clazz="itemlist" 
649      columns="<%=cc.getSetting("columns")%>"
650      sortby="<%=cc.getSortProperty()%>" 
651      direction="<%=cc.getSortDirection()%>"
652      title="<%=title%>"
653      action="index.jsp"
654      sc="<%=sc%>"
655      item="<%=itemType%>"
656      subcontext="<%=subContext%>"
657      >
658      <tbl:hidden 
659        name="bioassayset_id" 
660        value="<%=String.valueOf(bioAssaySetId)%>" 
661      />
662      <%
663      for (AnnotationType at : selectedAnnotationTypes.keySet())
664      {
665        %>
666        <tbl:columndef
667          id="<%="annotation." + at.getId()%>"
668          title="<%=HTML.encodeTags(at.getName()) %>"
669          show="always"
670        />
671        <%
672      }
673      %>
674      <tbl:columndef
675        id="bioassay"
676        property="COLUMN"
677        title="Bioassay"
678        show="always"
679        sortable="true"
680      />
681      <tbl:columndef
682        id="position"
683        property="POSITION"
684        title="Position"
685        show="<%=isAveraging ? "never" : "always" %>"
686        sortable="true"
687      />
688      <tbl:columndef
689        id="count"
690        title="Count"
691        show="<%=isAveraging ? "always" : "never" %>"
692      />
693      <%
694      for (int ch = 1; ch <= channels; ++ch)
695      {
696        %>
697        <tbl:columndef
698          id="<%="ch"+ch%>"
699          property="<%="%"+ch%>"
700          datatype="float"
701          title="<%="Ch " + ch%>"
702          tooltip="<%=transform.isTransformed() ? transform.toString() : null %>"
703          sortable="true"
704          filterable="true"
705          exportable="true"
706          formatter="<%=numberFormatter%>"
707        />
708        <%
709      }
710      %>
711      <%
712      for (TableColumn tc : columns)
713      {
714        %>
715        <tbl:columndef
716          id="<%=tc.getId()%>"
717          property="<%=tc.getProperty()%>"
718          datatype="<%=tc.getDatatype().getStringValue()%>"
719          title="<%=HTML.encodeTags(tc.getTitle())%>"
720          sortable="<%=tc.getSortable()%>"
721          filterable="<%=tc.getFilterable()%>"
722          exportable="<%=tc.getExportable()%>"
723          show="<%=!isAveraging || tc.isAveragable() ? tc.getShow() : "never"%>"
724          formatter="<%=tc.getFormatter()%>"
725        />
726        <%
727      }
728      %>
729       
730      <tbl:toolbar>
731        <tbl:button 
732          image="columns.gif" 
733          onclick="configureColumns()" 
734          title="Columns&hellip;" 
735          tooltip="Show, hide and re-order columns" 
736        />
737        <tbl:button 
738          image="plotter.gif"
739          onclick="assayPlot()"
740          title="Plot&hellip;"
741          tooltip="Plot selected data from this table"
742        />
743      </tbl:toolbar>
744      <tbl:data>
745        <tbl:columns />
746        <tbl:rows>
747        <%
748        int index = 0;
749        float[] intensity = new float[channels+1];
750        while (spotData.hasNext())
751        {
752          SqlResult item = spotData.next();
753          index++;
754          BioAssay bioAssay = explorer.getBioAssay(dc, item.getShort(1));
755          for (int ch = 1; ch <= channels; ++ch)
756          {
757            intensity[ch] = item.getFloat(2+ch);
758          }
759          %>
760          <tbl:row>
761            <%
762            for (Map.Entry<AnnotationType, AnnotationSummary> entry : selectedAnnotationTypes.entrySet())
763            {
764              AnnotationType at = entry.getKey();
765              AnnotationGroup annotationGroup = entry.getValue().getAnnotationGroup(bioAssay.getDataCubeColumnNo());
766              String allValues = annotationGroup.getTitle();
767              if (hasRatio)
768              {
769                float logRatio = (float)(Math.log(transform.unTransform(intensity[1]) / transform.unTransform(intensity[2])));
770                annotationGroup.addStatistics("logratio", logRatio);
771                annotationGroup.addStatistics("logratio2", logRatio * logRatio);
772              }
773              for (int ch = 1; ch <= channels; ++ch)
774              {
775                annotationGroup.addValue(ch, (float)transform.unTransform(intensity[ch]));
776              }
777              %>
778              <tbl:cell column="<%="annotation."+at.getId()%>" style="<%="background: "+annotationGroup.getColor()+";"%>">
779              <%=allValues%>
780              </tbl:cell>
781              <%
782            }
783            %>
784            <tbl:cell column="bioassay"><%=Base.getLinkedName(ID, bioAssay, false, true)%></tbl:cell>
785            <tbl:cell column="position"><%=item.getInt(2)%></tbl:cell>
786            <tbl:cell column="count"><%=item.getInt(2)%></tbl:cell>
787            <%
788            for (int ch = 1; ch <= channels; ++ch)
789            {
790              %>
791              <tbl:cell column="<%="ch" + ch%>" value="<%=intensity[ch]%>" />
792              <%
793            }
794            %>
795            <%
796            int colIndex = 3 + channels;
797            for (String columnId : selected.selectedIds)
798            {
799              %>
800              <tbl:cell column="<%=columnId%>" value="<%=item.getObject(colIndex++)%>" />
801              <%
802            }
803            %>
804          </tbl:row>
805          <%
806        }
807      %>
808      </tbl:rows>
809      </tbl:data>
810      </tbl:table>
811      </div>
812      <%
813      }
814      %>
815      <script language="JavaScript">
816      function init()
817      {
818        <%
819        for (Map.Entry<AnnotationType, AnnotationSummary> entry : selectedAnnotationTypes.entrySet())
820        {
821          AnnotationType at = entry.getKey();
822          AnnotationSummary summary = entry.getValue();
823          %>
824          <%
825          for (AnnotationGroup ag : summary.getAnnotationGroups())
826          {
827            for (int ch = 1; ch <= channels; ++ch)
828            {
829              %>
830              var div = document.getElementById('mean.<%=at.getId()%>.<%=ag.getId()%>.ch<%=ch%>');
831              div.innerHTML = '<%=Values.formatNumber(ag.getMean(ch), 2)%>';
832              <%
833            }
834            %>
835            var div = document.getElementById('count.<%=at.getId()%>.<%=ag.getId()%>');
836            div.innerHTML = '<%=ag.getCount(1)%>';
837            <%
838            if (hasRatio)
839            {
840              float r = ag.getStatistics("logratio");
841              int count = ag.getCount(1);
842              float gMean = count > 0 ? (float)Math.exp(r / count) : Float.NaN;
843              float sd = count > 1 ? 
844                (float)Math.sqrt((ag.getStatistics("logratio2") - r * (r / count))/(count-1))
845                : Float.NaN;
846              %>
847              var div = document.getElementById('gmean.<%=at.getId()%>.<%=ag.getId()%>');
848              div.innerHTML = '<%=Values.formatNumber(gMean, 2)%>';
849              var div = document.getElementById('sd.<%=at.getId()%>.<%=ag.getId()%>');
850              div.innerHTML = '<%=Values.formatNumber(sd, 2)%>';
851              <%
852            }
853          }
854        }
855        %>
856        MultiOptions.init();
857        var options = new Array();
858        <%
859        if (annotationTypes != null)
860        {
861          for (AnnotationType at : annotationTypes)
862          {
863            String isSelected = selectedAnnotationTypes.containsKey(at) ? "true" : "false";
864            %>
865            options[options.length] = {key:'<%=at.getId()%>', value:'<%=HTML.javaScriptEncode(at.getName())%>', selected:<%=isSelected%>};
866            <%
867          }
868        }
869        %>
870        MultiOptions.enableForField('annotationSummary', 'display:annotationTypes', 'annotationtype_id', 1, options);
871      }
872      Main.onLoad(init);
873      </script>
874     
875      </t:tab>
876      </t:tabcontrol>
877
878  </base:body>
879  </base:page>
880  <%
881}
882finally
883{
884  if (spotData != null) spotData.close();
885  if (dc != null) dc.close();
886}
887
888%>
Note: See TracBrowser for help on using the repository browser.