Changeset 1543


Ignore:
Timestamp:
Feb 28, 2012, 2:43:36 PM (12 years ago)
Author:
Nicklas Nordborg
Message:

References #364: Put RNA aliquots on bioplate to be used by the Caliper machine

Main features of the wizard has been implemented. Lots of minor details and error handling is not yet implemented.

Location:
extensions/net.sf.basedb.reggie/trunk
Files:
7 added
9 edited

Legend:

Unmodified
Added
Removed
  • extensions/net.sf.basedb.reggie/trunk/META-INF/servlets.xml

    r1518 r1543  
    3030  </servlet>
    3131  <servlet>
     32    <servlet-name>RnaQc</servlet-name>
     33    <servlet-class>net.sf.basedb.reggie.servlet.RnaQcServlet</servlet-class>
     34  </servlet>
     35  <servlet>
     36    <servlet-name>Subtype</servlet-name>
     37    <servlet-class>net.sf.basedb.reggie.servlet.SubtypeServlet</servlet-class>
     38  </servlet>
     39  <servlet>
    3240    <servlet-name>SampleReport</servlet-name>
    3341    <servlet-class>net.sf.basedb.reggie.servlet.SampleReportServlet</servlet-class>
  • extensions/net.sf.basedb.reggie/trunk/resources/css/base30.css

    r1538 r1543  
    3939}
    4040
     41.highlight:hover
     42{
     43  background-color: #F8F8E8 !important;
     44  border-top: 1px solid #2288AA !important;
     45  border-bottom: 1px solid #2288AA !important;
     46}
     47
     48.buttonclass.disabled, .buttonclass.disabled:hover
     49{
     50  color: #666666;
     51  background: #D0D0D0;
     52  cursor: default;
     53}
     54
     55.buttonclass.disabled img
     56{
     57  filter: gray; /* IE */
     58  opacity: 0.5;
     59}
     60
    4161.content
    4262{
     
    5777  overflow: auto;
    5878}
     79
     80
  • extensions/net.sf.basedb.reggie/trunk/resources/css/reggie.css

    r1538 r1543  
    9090.status.invalid:before
    9191{
    92   content: url('../../images/error.gif');
     92  content: url('../images/error.png');
    9393}
    9494.status.warning:before
    9595{
    96   content: url('../../images/warning.gif');
     96  content: url('../images/warning.png');
    9797}
    9898.status.valid:before
    9999{
    100   content: url('../../images/ok.gif');
     100  content: url('../images/ok.png');
    101101}
    102102.success ul
    103103{
    104   list-style-image: url('../../images/ok.gif');
     104  list-style-image: url('../images/ok.png');
    105105}
    106106
  • extensions/net.sf.basedb.reggie/trunk/resources/index.jsp

    r1538 r1543  
    224224          </dd>
    225225          <%
    226         }     
     226        }
     227        if (hasCreateExtractPermission)
     228        {
     229          %>
     230          <dt>
     231            <base:icon image="<%=home+"/images/rnaqc.png" %>" />
     232            RNA quality control wizards
     233          </dt>
     234          <dd>
     235            <ul>
     236            <li><a href="rnaqc_aliquot.jsp?ID=<%=ID%>">Create aliquots on Bioanalyzer/Caliper plates</a>
     237            <li><a href="rnaqc_plate_export.jsp?ID=<%=ID%>">Export Caliper plate information</a>
     238            <li><a href="rnaqc_plate_import.jsp?ID=<%=ID%>">Import RQS scores from Caliper data file</a>
     239            </ul>
     240          </dd>
     241          <%
     242        }
    227243        %>       
    228244        </dl>
  • extensions/net.sf.basedb.reggie/trunk/resources/install.jsp

    r1538 r1543  
    6363  var numIncomplete = 0;
    6464  var checks = response.checks;
     65  var tblHeader = '<tr><th class="itemTypeCol">Item type</th><th class="nameCol">Name</th><th class="iconCol"></th><th class="statusCol">Status</th></tr>';
    6566  var html = '<table class="report">';
    66   html += '<tr><th id="itemTypeCol">Item type</th><th id="nameCol">Name</th><th id="iconCol"></th><th id="statusCol">Status</th></tr>';
     67  html += tblHeader;
    6768  var lastItemType = null;
    6869  for (var i = 0; i < checks.length; i++)
     
    9293    if (lastItemType != check.itemType)
    9394    {
    94       html += '<tr class="newitemtype"><td>'+check.itemType+'</td>';
     95      if (check.itemType == 'ANNOTATIONTYPE')
     96      {
     97        // End the left side and start on the right
     98        html += '</table>';
     99        setInnerHTML('validationResult', html);
     100        html = '<table class="report">';
     101        html += tblHeader;
     102      }
     103      html += '<tr class="newitemtype highlight"><td>'+check.itemType+'</td>';
    95104    }
    96105    else
    97106    {
    98       html += '<tr class="sameitemtype"><td>&nbsp;</td>';
     107      html += '<tr class="sameitemtype highlight"><td>&nbsp;</td>';
    99108    }
    100109    lastItemType = check.itemType;
     
    125134  }
    126135  html += '</table>';
    127 
    128   setInnerHTML('validationResult', html);
     136  setInnerHTML('validationResult2', html);
    129137 
    130138  if (numErrors > 0)
     
    156164  width: 100%;
    157165  table-layout: fixed;
    158 }
    159 
    160 .report #itemTypeCol
    161 {
    162   width: 18em;
    163 }
    164 
    165 .report #nameCol
     166  border-collapse: collapse;
     167}
     168
     169.report .itemTypeCol
     170{
     171  width: 15em;
     172  overflow: hidden;
     173  text-overflow: ellipsis;
     174}
     175
     176.report .nameCol
    166177{
    167178  width: 20em;
    168 }
    169 .report #iconCol
     179  overflow: hidden;
     180  text-overflow: ellipsis;
     181}
     182.report .iconCol
    170183{
    171184  width: 20px;
    172185}
    173 .report #statusCol
     186.report .statusCol
    174187{}
    175188
     
    188201}
    189202
    190 .report .newitemtype td
     203.report .newitemtype
    191204{
    192205  border-top: 1px solid #A0A0A0;
    193206}
    194 .report .sameitemtype td
     207.report .sameitemtype
    195208{
    196209  border-top: 1px dotted #A0A0A0;
     210  border-bottom: 1px dotted #A0A0A0;
    197211}
    198212</style>
     
    207221  <div class="content" style="padding-left: 2em;">
    208222
    209     <div id="validationResult" class="absolutefull fullborder" style="bottom: 10em; left: 1em; right: 1em; ">
    210       Checking; please wait...
     223    <div class="absolutefull" style="width: 50%; bottom: 10em;">
     224      <div id="validationResult" class="absolutefull fullborder" style="left: 1em; right: 0.5em; ">
     225        Checking; please wait...
     226      </div>
     227    </div>
     228   
     229    <div class="absolutefull" style="width: 50%; bottom: 10em; left: auto;">
     230      <div id="validationResult2" class="absolutefull fullborder" style="left: 0.5em; right: 1em; ">
     231      </div>
    211232    </div>
    212233 
  • extensions/net.sf.basedb.reggie/trunk/resources/reggie.js

    r1532 r1543  
    270270  }
    271271}
     272
     273
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/Reggie.java

    r1536 r1543  
    1010import net.sf.basedb.core.AnnotationType;
    1111import net.sf.basedb.core.AnnotationTypeCategory;
     12import net.sf.basedb.core.BioPlateType;
    1213import net.sf.basedb.core.DbControl;
    1314import net.sf.basedb.core.Group;
     
    2425import net.sf.basedb.reggie.converter.DateToStringConverter;
    2526import net.sf.basedb.reggie.converter.StringToDateConverter;
     27import net.sf.basedb.reggie.dao.BioplateType;
    2628import net.sf.basedb.reggie.dao.Subtype;
    2729
     
    206208  public static final String ANNOTATION_BLOOD_SERUM = "BloodSerum";
    207209
     210  /**
     211    The name of the "QCRunDate" annotation, used
     212    for bioplates (RNA). It is a date annotation type.
     213    @since 2.4
     214  */
     215  public static final String ANNOTATION_QC_RUN_DATE = "QCRunDate";
     216
     217  /**
     218    The name of the "QCOperator" annotation, used
     219    for bioplates (RNA). It is a string annotation type.
     220    @since 2.4
     221  */
     222  public static final String ANNOTATION_QC_OPERATOR = "QCOperator";
     223 
    208224  /**
    209225    Default converter for date values to string values: yyyyMMdd
     
    270286    return s;
    271287  }
     288 
     289  /**
     290    List all bioplate types with given name.
     291    @since 2.4
     292  */
     293  public static List<BioPlateType> listBioPlateTypes(DbControl dc, BioplateType plateType)
     294  {
     295    ItemQuery<BioPlateType> query = BioPlateType.getQuery();
     296    query.restrict(
     297      Restrictions.eq(
     298        Hql.property("name"),
     299        Expressions.parameter("name", plateType.getName(), Type.STRING)
     300      ));
     301    query.include(Include.ALL);
     302    return query.list(dc);
     303  }
     304
     305  /**
     306    Find a single bioplate type with the given name. If exactly one is found it
     307    is returned, otherwise null is returned or an exception is thrown
     308    depending on the exceptionIfNotFound parameter.
     309    @since 2.4
     310  */
     311  public static BioPlateType findBioplateType(DbControl dc, BioplateType plateType, boolean exceptionIfNotFound)
     312  {
     313    ItemQuery<BioPlateType> query = BioPlateType.getQuery();
     314    query.restrict(
     315      Restrictions.eq(
     316        Hql.property("name"),
     317        Expressions.parameter("name", plateType.getName(), Type.STRING)
     318      ));
     319    query.include(Include.ALL);
     320    List<BioPlateType> result = listBioPlateTypes(dc, plateType);
     321    BioPlateType s = null;
     322    if (result.size() == 0)
     323    {
     324      if (exceptionIfNotFound) throw new ItemNotFoundException("BioPlateType["+plateType.getName()+"]");
     325    }
     326    else if (result.size() > 1)
     327    {
     328      if (exceptionIfNotFound) throw new InvalidDataException("Found > 1 BioPlateType["+plateType.getName()+"]");
     329    }
     330    else
     331    {
     332      s = result.get(0);
     333    }
     334    return s;
     335  }
     336
    272337 
    273338  /**
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Subtype.java

    r1526 r1543  
    11package net.sf.basedb.reggie.dao;
     2
     3import org.json.simple.JSONObject;
    24
    35import net.sf.basedb.core.DbControl;
     
    810import net.sf.basedb.core.query.Expressions;
    911import net.sf.basedb.core.query.Hql;
     12import net.sf.basedb.core.query.Restriction;
    1013import net.sf.basedb.core.query.Restrictions;
    1114import net.sf.basedb.reggie.Reggie;
     
    6972  public static final Subtype LYSATE = new Subtype("Lysate", Item.EXTRACT);
    7073
    71 
     74  /**
     75    The definition of the "DNA" extract subtype.
     76    @since 2.4
     77  */
     78  public static final Subtype DNA = new Subtype("DNA", Item.EXTRACT);
     79
     80  /**
     81    The definition of the "RNA" extract subtype.
     82    @since 2.4
     83  */
     84  public static final Subtype RNA = new Subtype("RNA", Item.EXTRACT);
     85
     86  /**
     87    The definition of the "RNA Quality control" extract subtype.
     88    @since 2.4
     89  */
     90  public static final Subtype RNAQC = new Subtype("RNAQC", Item.EXTRACT);
     91
     92 
     93  /**
     94    The definition of the "Quality control" protocol subtype.
     95    @since 2.4
     96  */
     97  public static final Subtype QUALITY_CONTROL = new Subtype("Quality control", Item.PROTOCOL);
     98 
     99  /**
     100    Create a subtype representation of an ItemSubtype object.
     101    @since 2.4
     102  */
     103  public static final Subtype get(ItemSubtype subtype)
     104  {
     105    Subtype s = new Subtype(subtype.getName(), subtype.getMainItemType());
     106    s.id = subtype.getId();
     107    return s;
     108  }
    72109 
    73110  private final String name;
    74111  private final Item mainType;
    75112  private int id;
     113  private JSONObject json;
    76114 
    77115  /**
     
    85123    this.mainType = mainType;
    86124  }
    87    
     125 
    88126  /**
    89127    Get the name of the subtype.
     
    100138  {
    101139    return mainType;
     140  }
     141 
     142  /**
     143    Get the subtype information as a JSON object ready to be sent as an AJAX response.
     144    @since 2.4
     145  */
     146  @SuppressWarnings("unchecked")
     147  public JSONObject asJSONObject(DbControl dc)
     148  {
     149    if (json == null)
     150    {
     151      if (id==0) load(dc); // Ensure that the subtype has been loaded
     152      json = new JSONObject();
     153      json.put("id", id);
     154      json.put("name", getName());
     155      json.put("mainType", getMainType().name());
     156    }
     157    return json;
    102158  }
    103159 
     
    146202    @since 2.1
    147203  */
    148   public void addFilter(DbControl dc, ItemQuery<? extends Subtypable> query, String alias)
     204  public void addFilter(DbControl dc, ItemQuery<?> query, String alias)
     205  {
     206    query.restrict(restriction(dc, alias));
     207  }
     208 
     209  public Restriction restriction(DbControl dc, String alias)
    149210  {
    150211    if (id==0) load(dc); // Ensure that the subtype has been loaded
    151     query.restrict(Restrictions.eq(Hql.property(alias, "itemSubtype"), Expressions.integer(id)));
    152   }
    153  
     212    return Restrictions.eq(Hql.property(alias, "itemSubtype.id"), Expressions.integer(id));
     213  }
     214
    154215}
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/InstallServlet.java

    r1526 r1543  
    1919import net.sf.basedb.core.AnnotationTypeCategory;
    2020import net.sf.basedb.core.Application;
     21import net.sf.basedb.core.BioPlateType;
    2122import net.sf.basedb.core.DbControl;
    2223import net.sf.basedb.core.Group;
     
    3233import net.sf.basedb.core.Type;
    3334import net.sf.basedb.reggie.Reggie;
     35import net.sf.basedb.reggie.dao.BioplateType;
    3436import net.sf.basedb.reggie.dao.Subtype;
    3537import net.sf.basedb.util.EqualsHelper;
     
    106108        jsonChecks.add(checkSubtype(dc, Subtype.HISTOLOGY, createIfMissing, Subtype.SPECIMEN));
    107109        jsonChecks.add(checkSubtype(dc, Subtype.LYSATE, createIfMissing, Subtype.SPECIMEN));
     110        jsonChecks.add(checkSubtype(dc, Subtype.DNA, createIfMissing, Subtype.LYSATE));
     111        jsonChecks.add(checkSubtype(dc, Subtype.RNA, createIfMissing, Subtype.LYSATE));
     112        jsonChecks.add(checkSubtype(dc, Subtype.QUALITY_CONTROL, createIfMissing));
     113        jsonChecks.add(checkSubtype(dc, Subtype.RNAQC, createIfMissing, Subtype.RNA, Subtype.QUALITY_CONTROL));
     114
     115        // Bioplate types
     116        jsonChecks.add(checkBioplateType(dc, BioplateType.BA_RNAQC, createIfMissing));
     117        jsonChecks.add(checkBioplateType(dc, BioplateType.CALIPER_RNAQC, createIfMissing));
    108118       
    109119        // Annotation type checks
     
    165175            null, effectiveOptions, createIfMissing));       
    166176        jsonChecks.add(checkAnnotationType(dc, Reggie.ANNOTATION_PARTITION_DATE, new Item[]{Item.SAMPLE, Item.EXTRACT}, Type.DATE, 1,
     177            null, effectiveOptions, createIfMissing));
     178        jsonChecks.add(checkAnnotationType(dc, Reggie.ANNOTATION_QC_RUN_DATE, new Item[] { Item.BIOPLATE}, Type.DATE, 1,
     179            null, effectiveOptions, createIfMissing));
     180        jsonChecks.add(checkAnnotationType(dc, Reggie.ANNOTATION_QC_OPERATOR, new Item[] { Item.BIOPLATE}, Type.STRING, 1,
    167181            null, effectiveOptions, createIfMissing));
    168182       
     
    192206            Reggie.ANNOTATION_PARTITION_DATE));
    193207       
     208        jsonChecks.add(checkAnnotationTypeCategory(dc, Subtype.RNA, createIfMissing,
     209            Reggie.ANNOTATION_QC_RUN_DATE, Reggie.ANNOTATION_QC_OPERATOR));
     210       
     211
     212        jsonChecks.add(checkAnnotationTypeCategory(dc, Subtype.DNA, createIfMissing));
     213
     214        jsonChecks.add(checkAnnotationTypeCategory(dc, Subtype.RNAQC, createIfMissing));
     215       
    194216        json.put("checks", jsonChecks);
    195217      }
    196      
    197218    }
    198219    catch (Throwable t)
     
    722743  }
    723744
     745  /**
     746    Create a bioplate type with the given options. The bioplate type is created in
     747    a separate transaction.
     748    @since 2.4
     749  */
     750  public BioPlateType createBioPlateType(SessionControl sc, BioplateType def)
     751  {
     752    BioPlateType plateType = null;
     753    DbControl dc = sc.newDbControl();
     754    try
     755    {
     756      plateType = BioPlateType.getNew(dc);
     757      plateType.setName(def.getName());
     758      plateType.setBioMaterialType(def.getBioMaterialType());
     759      if (def.getSubtype() != null)
     760      {
     761        plateType.setItemSubtype(def.getSubtype().load(dc));
     762      }
     763      plateType.setLockMode(def.getLockMode());
     764     
     765      dc.saveItem(plateType);
     766      dc.commit();
     767    }
     768    finally
     769    {
     770      if (dc != null) dc.close();
     771    }
     772    return plateType;
     773  }
     774
     775 
     776  /**
     777    Check for an existing bioplate type with the given options.
     778    A JSONObject is returned with the result. The following
     779    keys are used:
     780    <ul>
     781    <li>itemType: BIOPLATETYPE
     782    <li>name: The name of the bioplate type
     783    <li>id: The id of the bioplate type if it exists
     784    <li>bioMaterialType: The bioMaterial type that can be used on bioplates with the given type
     785    <li>status: ok, error, or missing
     786    <li>message: A descriptive message in case of an error
     787    </ul>
     788    @since 2.0
     789  */
     790  @SuppressWarnings("unchecked")
     791  public JSONObject checkBioplateType(DbControl dc, BioplateType plateType,
     792    boolean createIfMissing)
     793  {
     794 
     795    JSONObject json = new JSONObject();
     796    JSONArray jsonMessages = new JSONArray();
     797    json.put("itemType", Item.BIOPLATETYPE.name());
     798    json.put("name", plateType.getName());
     799    json.put("bioMaterialType", plateType.getBioMaterialType().name());
     800   
     801    List<BioPlateType> result = Reggie.listBioPlateTypes(dc, plateType);
     802    if (result.size() == 0)
     803    {
     804      if (createIfMissing)
     805      {
     806        BioPlateType t = createBioPlateType(dc.getSessionControl(), plateType);
     807        json.put("id", t.getId());
     808        json.put("status", "ok");
     809        jsonMessages.add("Created");
     810      }
     811      else
     812      {
     813        json.put("status", "missing");
     814        jsonMessages.add("Not found");
     815      }
     816    }
     817    else if (result.size() > 1)
     818    {
     819      json.put("status", "error");
     820      jsonMessages.add("Found > 1 bioplate type");
     821    }
     822    else
     823    {
     824      BioPlateType t = result.get(0);
     825      json.put("id", t.getId());
     826      json.put("status", "ok"); // For now -- more checks below
     827     
     828      if (t.getBioMaterialType() != plateType.getBioMaterialType())
     829      {
     830        json.put("status", "error");
     831        jsonMessages.add("Can't be used by '" + plateType.getBioMaterialType() + "' items.");
     832      }
     833     
     834      Subtype subtype = plateType.getSubtype();
     835      if (subtype != null)
     836      {
     837        if (!subtype.load(dc).equals(t.getItemSubtype()))
     838        {
     839          json.put("status", "error");
     840          jsonMessages.add("Should be locked to '" + subtype.getName() + "' (" + subtype.getMainType() + ") items.");
     841        }
     842      }
     843     
     844      if (t.getLockMode() != plateType.getLockMode())
     845      {
     846        json.put("status", "error");
     847        jsonMessages.add("Should be using '" + plateType.getLockMode().name() + "' well lock mode");
     848      }
     849    }
     850    if (jsonMessages.size() == 0) jsonMessages.add("Ok");
     851    json.put("messages", jsonMessages);
     852    return json;
     853 
     854  }
     855
    724856
    725857  /**
Note: See TracChangeset for help on using the changeset viewer.