extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/ScanBQuarterMonthReportServlet.java

Code
Comments
Other
Rev Date Author Line
1820 06 Feb 13 olle 1 package net.sf.basedb.reggie.servlet;
1820 06 Feb 13 olle 2
1820 06 Feb 13 olle 3 import java.io.IOException;
1820 06 Feb 13 olle 4 import java.util.Collections;
1820 06 Feb 13 olle 5 import java.util.Date;
1820 06 Feb 13 olle 6 import java.util.HashMap;
3907 29 Apr 16 nicklas 7 import java.util.HashSet;
3907 29 Apr 16 nicklas 8 import java.util.Iterator;
1820 06 Feb 13 olle 9 import java.util.ArrayList;
1820 06 Feb 13 olle 10 import java.util.List;
3907 29 Apr 16 nicklas 11 import java.util.Set;
1820 06 Feb 13 olle 12
1820 06 Feb 13 olle 13 import javax.servlet.ServletException;
1820 06 Feb 13 olle 14 import javax.servlet.http.HttpServlet;
1820 06 Feb 13 olle 15 import javax.servlet.http.HttpServletRequest;
1820 06 Feb 13 olle 16 import javax.servlet.http.HttpServletResponse;
1820 06 Feb 13 olle 17
2608 28 Aug 14 nicklas 18 import net.sf.basedb.clients.web.util.HTML;
1914 21 Mar 13 nicklas 19 import net.sf.basedb.core.BioMaterial;
1820 06 Feb 13 olle 20 import net.sf.basedb.core.DbControl;
1820 06 Feb 13 olle 21 import net.sf.basedb.core.Extract;
1820 06 Feb 13 olle 22 import net.sf.basedb.core.ItemQuery;
1820 06 Feb 13 olle 23 import net.sf.basedb.core.ItemSubtype;
1820 06 Feb 13 olle 24 import net.sf.basedb.core.Sample;
1820 06 Feb 13 olle 25 import net.sf.basedb.core.SessionControl;
3907 29 Apr 16 nicklas 26 import net.sf.basedb.core.SimpleProgressReporter;
2608 28 Aug 14 nicklas 27 import net.sf.basedb.core.query.Annotations;
2608 28 Aug 14 nicklas 28 import net.sf.basedb.core.query.Expressions;
1820 06 Feb 13 olle 29 import net.sf.basedb.core.query.Hql;
1820 06 Feb 13 olle 30 import net.sf.basedb.core.query.Orders;
1820 06 Feb 13 olle 31 import net.sf.basedb.core.query.Restrictions;
1820 06 Feb 13 olle 32 import net.sf.basedb.core.snapshot.SnapshotManager;
2598 22 Aug 14 nicklas 33 import net.sf.basedb.reggie.JsonUtil;
1820 06 Feb 13 olle 34 import net.sf.basedb.reggie.Reggie;
1820 06 Feb 13 olle 35 import net.sf.basedb.reggie.Site;
1820 06 Feb 13 olle 36 import net.sf.basedb.reggie.converter.DateToStringConverter;
1820 06 Feb 13 olle 37 import net.sf.basedb.reggie.dao.Annotationtype;
1820 06 Feb 13 olle 38 import net.sf.basedb.reggie.dao.Subtype;
1820 06 Feb 13 olle 39 import net.sf.basedb.util.Values;
1820 06 Feb 13 olle 40 import net.sf.basedb.util.error.ThrowableUtil;
1820 06 Feb 13 olle 41
7024 07 Feb 23 nicklas 42 import org.apache.commons.lang3.time.FastDateFormat;
1820 06 Feb 13 olle 43 import org.json.simple.JSONArray;
1820 06 Feb 13 olle 44 import org.json.simple.JSONObject;
1820 06 Feb 13 olle 45
1820 06 Feb 13 olle 46 public class ScanBQuarterMonthReportServlet
1820 06 Feb 13 olle 47   extends HttpServlet 
1820 06 Feb 13 olle 48 {
1820 06 Feb 13 olle 49   private static final long serialVersionUID = -7481987405276528027L;
1820 06 Feb 13 olle 50
2611 29 Aug 14 nicklas 51   private ReportTableUtil tableUtil;
1842 14 Feb 13 olle 52
1842 14 Feb 13 olle 53   private static int numberOfDecimals = 1;
1842 14 Feb 13 olle 54
1820 06 Feb 13 olle 55   // Use stored annotation snapshots for performance reasons
1820 06 Feb 13 olle 56   private SnapshotManager snapshotManager;
1820 06 Feb 13 olle 57   
1820 06 Feb 13 olle 58   private SnapshotManager getSnapshotManager()
1820 06 Feb 13 olle 59   {
1820 06 Feb 13 olle 60     if (this.snapshotManager == null)
1820 06 Feb 13 olle 61     {
1820 06 Feb 13 olle 62       this.snapshotManager = new SnapshotManager();        
1820 06 Feb 13 olle 63     }
1820 06 Feb 13 olle 64     return this.snapshotManager;
1820 06 Feb 13 olle 65   }
1820 06 Feb 13 olle 66
1820 06 Feb 13 olle 67   // Constants for view types not defined in ReportTableUtilServlet
1820 06 Feb 13 olle 68   public static final String quarterMonthView = "QUARTERMONTH";
1820 06 Feb 13 olle 69   // Constants for chart variant choices
1820 06 Feb 13 olle 70   public static final String allCharts = "allcharts";
1820 06 Feb 13 olle 71   public static final String originalQuantityTissueChart = "originalquantitytissue";
1820 06 Feb 13 olle 72   public static final String quantityTissueUsedChart = "quantitytissueused";
1820 06 Feb 13 olle 73   public static final String histologyPieceQuantityChart = "histologypiecequantity";
1820 06 Feb 13 olle 74   public static final String remainingQuantityForScanBSpecimenChart = "remainingquantityforscanbspecimen";
1820 06 Feb 13 olle 75   public static final String originalQuantityDnaChart = "originalquantitydna";
1820 06 Feb 13 olle 76   public static final String originalQuantityRnaChart = "originalquantityrna";
1820 06 Feb 13 olle 77   public static final String dnaYieldChart = "dnayield";
1820 06 Feb 13 olle 78   public static final String rnaYieldChart = "rnayield";
1820 06 Feb 13 olle 79   public static final String dnaYieldCorrectedChart = "dnayieldcorrected";
1820 06 Feb 13 olle 80   public static final String rnaYieldCorrectedChart = "rnayieldcorrected";
1820 06 Feb 13 olle 81   public static final String rnaQcChart = "rnaqc";
1820 06 Feb 13 olle 82   public static final String minutesToRnaLaterChart = "minutestornalater";
1820 06 Feb 13 olle 83
1820 06 Feb 13 olle 84   private List<String> chartVariantList = null;
1820 06 Feb 13 olle 85   /**
1820 06 Feb 13 olle 86    *  Returns a list of all chart variant strings.
1820 06 Feb 13 olle 87    *
1820 06 Feb 13 olle 88    *  @return List<String> A list of all chart variant strings.
1820 06 Feb 13 olle 89    */
1820 06 Feb 13 olle 90   public List<String> getChartVariantList()
1820 06 Feb 13 olle 91   {
1820 06 Feb 13 olle 92     if (this.chartVariantList == null)
1820 06 Feb 13 olle 93     {
1820 06 Feb 13 olle 94       // Initialize list with chart variants
1820 06 Feb 13 olle 95       this.chartVariantList = new ArrayList<String>();
1820 06 Feb 13 olle 96       this.chartVariantList.add(originalQuantityTissueChart);
1820 06 Feb 13 olle 97       this.chartVariantList.add(quantityTissueUsedChart);
1820 06 Feb 13 olle 98       this.chartVariantList.add(histologyPieceQuantityChart);
1820 06 Feb 13 olle 99       this.chartVariantList.add(remainingQuantityForScanBSpecimenChart);
1820 06 Feb 13 olle 100       this.chartVariantList.add(originalQuantityDnaChart);
1820 06 Feb 13 olle 101       this.chartVariantList.add(originalQuantityRnaChart);
1820 06 Feb 13 olle 102       this.chartVariantList.add(dnaYieldChart);
1820 06 Feb 13 olle 103       this.chartVariantList.add(rnaYieldChart);
1820 06 Feb 13 olle 104       this.chartVariantList.add(dnaYieldCorrectedChart);
1820 06 Feb 13 olle 105       this.chartVariantList.add(rnaYieldCorrectedChart);
1820 06 Feb 13 olle 106       this.chartVariantList.add(rnaQcChart);
1820 06 Feb 13 olle 107       this.chartVariantList.add(minutesToRnaLaterChart);
1820 06 Feb 13 olle 108     }
1820 06 Feb 13 olle 109     return this.chartVariantList;
1820 06 Feb 13 olle 110   }
1820 06 Feb 13 olle 111
1820 06 Feb 13 olle 112   private int minItemsForStatisticsCalculation = 5;
3907 29 Apr 16 nicklas 113   private Set<Sample> allSamples = new HashSet<Sample>();
1820 06 Feb 13 olle 114   private List<Sample> sampleHistologyList = new ArrayList<Sample>();
1837 13 Feb 13 olle 115   private List<Sample> sampleNegativeMinToRnaLaterList = new ArrayList<Sample>();
1837 13 Feb 13 olle 116   private List<Sample> sampleZeroMinToRnaLaterList = new ArrayList<Sample>();
3907 29 Apr 16 nicklas 117   private Set<Extract> allLysates = new HashSet<Extract>();
1820 06 Feb 13 olle 118   private List<Extract> extractDnaList = new ArrayList<Extract>();
1820 06 Feb 13 olle 119   private List<Extract> extractRnaList = new ArrayList<Extract>();
1820 06 Feb 13 olle 120   private List<Extract> extractRnaQcList = new ArrayList<Extract>();
3907 29 Apr 16 nicklas 121   private Set<Integer> rnaQcGrandParentSampleIds = new HashSet<Integer>();
1820 06 Feb 13 olle 122
1820 06 Feb 13 olle 123   private HashMap<Integer, Date> sampleIdQiaCubeDateHashMap = new HashMap<Integer, Date>();
1820 06 Feb 13 olle 124   private HashMap<Integer, Date> sampleIdSamplingDateHashMap = new HashMap<Integer, Date>();
1837 13 Feb 13 olle 125   private HashMap<Integer, Date> sampleIdRnaLaterDateHashMap = new HashMap<Integer, Date>();
1820 06 Feb 13 olle 126   private HashMap<Integer, Float> sampleIdTissueQuantityUsedHashMap = new HashMap<Integer, Float>();
1820 06 Feb 13 olle 127   private HashMap<Integer, Long> sampleIdMinToRnaLaterHashMap = new HashMap<Integer, Long>();
1820 06 Feb 13 olle 128   private HashMap<Integer, Date> extractIdQiaCubeDateHashMap = new HashMap<Integer, Date>();
1820 06 Feb 13 olle 129   private HashMap<Integer, Integer> extractIdSampleIdHashMap = new HashMap<Integer, Integer>();
1820 06 Feb 13 olle 130   private HashMap<Integer, Float> extractIdRqsHashMap = new HashMap<Integer, Float>();
1820 06 Feb 13 olle 131   private HashMap<Integer, Float> extractIdRinHashMap = new HashMap<Integer, Float>();
1820 06 Feb 13 olle 132
1820 06 Feb 13 olle 133   private HashMap<Integer, Float> getSampleIdTissueQuantityUsedHashMap()
1820 06 Feb 13 olle 134   {
1820 06 Feb 13 olle 135     // Create hash map if not existing
1820 06 Feb 13 olle 136     if (this.sampleIdTissueQuantityUsedHashMap == null)
1820 06 Feb 13 olle 137     {
1820 06 Feb 13 olle 138       this.sampleIdTissueQuantityUsedHashMap = new HashMap<Integer, Float>();
1820 06 Feb 13 olle 139     }
1820 06 Feb 13 olle 140     return this.sampleIdTissueQuantityUsedHashMap;
1820 06 Feb 13 olle 141   }
1820 06 Feb 13 olle 142
1820 06 Feb 13 olle 143   private void setSampleIdTissueQuantityUsedHashMap(HashMap<Integer, Float> sampleIdTissueQuantityUsedHashMap)
1820 06 Feb 13 olle 144   {
1820 06 Feb 13 olle 145     this.sampleIdTissueQuantityUsedHashMap = sampleIdTissueQuantityUsedHashMap;
1820 06 Feb 13 olle 146   }
1820 06 Feb 13 olle 147
1825 07 Feb 13 olle 148   private int numRemainingTissueItemsGT1Mg = 0;
1825 07 Feb 13 olle 149   
1825 07 Feb 13 olle 150   public int getNumRemainingTissueItemsGT1Mg()
1825 07 Feb 13 olle 151   {
1825 07 Feb 13 olle 152     return this.numRemainingTissueItemsGT1Mg;
1825 07 Feb 13 olle 153   }
1825 07 Feb 13 olle 154   
1825 07 Feb 13 olle 155   private void setNumRemainingTissueItemsGT1Mg(int numRemainingTissueItemsGT1Mg)
1825 07 Feb 13 olle 156   {
1825 07 Feb 13 olle 157     this.numRemainingTissueItemsGT1Mg = numRemainingTissueItemsGT1Mg;
1825 07 Feb 13 olle 158   }
1825 07 Feb 13 olle 159
1820 06 Feb 13 olle 160   public ScanBQuarterMonthReportServlet()
1820 06 Feb 13 olle 161   {
1820 06 Feb 13 olle 162     // Create new instance of ReportTableUtilServlet for common report table utilities
2611 29 Aug 14 nicklas 163     tableUtil = new ReportTableUtil();
1820 06 Feb 13 olle 164   }
2008 19 Jun 13 olle 165
2008 19 Jun 13 olle 166
1820 06 Feb 13 olle 167   @Override
1820 06 Feb 13 olle 168   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
1820 06 Feb 13 olle 169     throws ServletException, IOException 
1820 06 Feb 13 olle 170   {  
1820 06 Feb 13 olle 171     String cmd = req.getParameter("cmd");
2598 22 Aug 14 nicklas 172     JsonUtil.setJsonResponseHeaders(resp);
1820 06 Feb 13 olle 173     
1820 06 Feb 13 olle 174     JSONObject json = new JSONObject();
1820 06 Feb 13 olle 175     json.put("status", "ok");
1820 06 Feb 13 olle 176     
3975 26 May 16 nicklas 177     final SessionControl sc = Reggie.getSessionControl(req);
1820 06 Feb 13 olle 178     DbControl dc = null;    
6337 16 Jun 21 nicklas 179     dc = sc.newDbControl(":Sample processing statistics");        
1820 06 Feb 13 olle 180     
1820 06 Feb 13 olle 181     try
1820 06 Feb 13 olle 182     {
2608 28 Aug 14 nicklas 183       if ("GetSites".equals(cmd))
1997 28 May 13 olle 184       {
2611 29 Aug 14 nicklas 185         json.put("sites", ReportTableUtil.getJSONSites(Site.SORT_BY_NAME));
1997 28 May 13 olle 186       }
1997 28 May 13 olle 187       else if ("scanbquartermonthreport".equals(cmd))
3907 29 Apr 16 nicklas 188       {
3907 29 Apr 16 nicklas 189         SimpleProgressReporter progress = new SimpleProgressReporter(null);
3907 29 Apr 16 nicklas 190         sc.setSessionSetting("scanbquartermonthreport-progress", progress);
3907 29 Apr 16 nicklas 191         progress.display(1, "Loading samples...");
3907 29 Apr 16 nicklas 192         
1820 06 Feb 13 olle 193         String startDateParameter = Values.getString(req.getParameter("fdate"), null);
1820 06 Feb 13 olle 194         String endDateParameter = Values.getString(req.getParameter("tdate"), null);
1820 06 Feb 13 olle 195
1820 06 Feb 13 olle 196         Date startDate = Reggie.CONVERTER_STRING_TO_DATE.convert(startDateParameter);
1820 06 Feb 13 olle 197         Date endDate = Reggie.CONVERTER_STRING_TO_DATE.convert(endDateParameter);
1820 06 Feb 13 olle 198         
1820 06 Feb 13 olle 199         if (startDate == null)
1820 06 Feb 13 olle 200         {
1820 06 Feb 13 olle 201           // Get the when the first site started
1820 06 Feb 13 olle 202           for (Site s : Site.getAllSites())
1820 06 Feb 13 olle 203           {
1820 06 Feb 13 olle 204             Date siteDate = Reggie.CONVERTER_STRING_TO_DATE.convert(s.getStartDate().replaceAll("-", ""));
1820 06 Feb 13 olle 205             if (siteDate != null && (startDate == null || startDate.after(siteDate))) 
1820 06 Feb 13 olle 206             {
1820 06 Feb 13 olle 207               startDate = siteDate;            
1820 06 Feb 13 olle 208             }
1820 06 Feb 13 olle 209           }
1820 06 Feb 13 olle 210         }
1820 06 Feb 13 olle 211         if (endDate == null) 
1820 06 Feb 13 olle 212         {
1820 06 Feb 13 olle 213           // Get the date for today
1820 06 Feb 13 olle 214           endDate = new Date();
1820 06 Feb 13 olle 215         }
1820 06 Feb 13 olle 216
1820 06 Feb 13 olle 217         String viewType = null;
1820 06 Feb 13 olle 218         String viewTypeParameter = Values.getString(req.getParameter("vtype"), null);
2611 29 Aug 14 nicklas 219         if (viewTypeParameter != null && !viewTypeParameter.equals(ReportTableUtil.autoView))
1820 06 Feb 13 olle 220         {
1820 06 Feb 13 olle 221           viewType = viewTypeParameter;
1820 06 Feb 13 olle 222         }
1820 06 Feb 13 olle 223         else
1820 06 Feb 13 olle 224         {
1820 06 Feb 13 olle 225           // Auto view type
1820 06 Feb 13 olle 226           viewType = tableUtil.getViewType(startDate, endDate);
1820 06 Feb 13 olle 227           // Use month view instead of week view
2611 29 Aug 14 nicklas 228           if (viewType.equals(ReportTableUtil.weekView))
1820 06 Feb 13 olle 229           {
2611 29 Aug 14 nicklas 230             viewType = ReportTableUtil.monthView;
1820 06 Feb 13 olle 231           }
1820 06 Feb 13 olle 232         }
2608 28 Aug 14 nicklas 233         String sitePrefix = Values.getStringOrNull(req.getParameter("site"));
2608 28 Aug 14 nicklas 234         Site site = sitePrefix != null ? Site.findByCaseName(sitePrefix) : null;
2608 28 Aug 14 nicklas 235         String chartVariant = Values.getString(req.getParameter("cvariant"), originalQuantityTissueChart);
1820 06 Feb 13 olle 236
3907 29 Apr 16 nicklas 237         json = createScanBQuarterMonthReport(dc, json, startDate, endDate, viewType, chartVariant, site, progress);
3907 29 Apr 16 nicklas 238         progress.display(100, "Done");
1820 06 Feb 13 olle 239       }
1820 06 Feb 13 olle 240     }
1820 06 Feb 13 olle 241     catch (Throwable t)
1820 06 Feb 13 olle 242     {
1820 06 Feb 13 olle 243       t.printStackTrace();
1820 06 Feb 13 olle 244       json.clear();
1820 06 Feb 13 olle 245       json.put("status", "error");
1820 06 Feb 13 olle 246       json.put("message", t.getMessage());
1820 06 Feb 13 olle 247       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
1820 06 Feb 13 olle 248     }
1820 06 Feb 13 olle 249     finally
1820 06 Feb 13 olle 250     {
1820 06 Feb 13 olle 251       if (dc != null) dc.close();
3907 29 Apr 16 nicklas 252       if (sc != null) sc.setSessionSetting("scanbquartermonthreport-progress", null);
1820 06 Feb 13 olle 253       json.writeJSONString(resp.getWriter());
1820 06 Feb 13 olle 254     }
1820 06 Feb 13 olle 255   }
1997 28 May 13 olle 256
3907 29 Apr 16 nicklas 257   private JSONObject createScanBQuarterMonthReport(DbControl dc, JSONObject json, Date startDate, Date endDate, String viewType, String chartVariant, Site site, SimpleProgressReporter progress)
1997 28 May 13 olle 258     throws ServletException, IOException 
1997 28 May 13 olle 259   {  
1820 06 Feb 13 olle 260     JSONObject jsonReport = new JSONObject();
1820 06 Feb 13 olle 261     //
1820 06 Feb 13 olle 262     // Sample raw list
1820 06 Feb 13 olle 263     ItemQuery<Sample> sampleQuery = Sample.getQuery();
1820 06 Feb 13 olle 264     sampleQuery.joinPermanent(Hql.innerJoin(null, "creationEvent", "ce", true));
2608 28 Aug 14 nicklas 265     // ...only include 'Specimen' and 'Histology'
1820 06 Feb 13 olle 266     sampleQuery.restrict(
1820 06 Feb 13 olle 267       Restrictions.or(
1820 06 Feb 13 olle 268         Subtype.SPECIMEN.restriction(dc, null),
2608 28 Aug 14 nicklas 269         Subtype.HISTOLOGY.restriction(dc, null)
1820 06 Feb 13 olle 270       ));
2608 28 Aug 14 nicklas 271     if (site != null)
2608 28 Aug 14 nicklas 272     {
2608 28 Aug 14 nicklas 273       // Restrict by site
2608 28 Aug 14 nicklas 274       sampleQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(site.getPrefix() + "%")));
2608 28 Aug 14 nicklas 275     }
2608 28 Aug 14 nicklas 276     // Filter on original quantity > 0
2608 28 Aug 14 nicklas 277     sampleQuery.restrict(Restrictions.gt(Hql.property("originalQuantity"), Expressions.aFloat(0f)));
2608 28 Aug 14 nicklas 278     // Filter on BiopsyType == null
2608 28 Aug 14 nicklas 279     sampleQuery.join(Annotations.leftJoin(Annotationtype.BIOPSY_TYPE.get(dc), "bt"));
2608 28 Aug 14 nicklas 280     sampleQuery.restrict(Restrictions.eq(Hql.alias("bt"), null));
1820 06 Feb 13 olle 281     sampleQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1820 06 Feb 13 olle 282     sampleQuery.order(Orders.asc(Hql.property("name")));
1820 06 Feb 13 olle 283     sampleQuery.order(Orders.asc(Hql.property("ce", "eventDate")));
1820 06 Feb 13 olle 284     sampleQuery.setCacheResult(true);
2608 28 Aug 14 nicklas 285
3907 29 Apr 16 nicklas 286
1820 06 Feb 13 olle 287     // Extract raw list
1820 06 Feb 13 olle 288     ItemQuery<Extract> extractQuery = Extract.getQuery();
1820 06 Feb 13 olle 289     extractQuery.joinPermanent(Hql.innerJoin(null, "creationEvent", "ce", true));
1820 06 Feb 13 olle 290     // ...only include 'Lysate', 'DNA', 'RNA', or 'RNAQC' items
1820 06 Feb 13 olle 291     extractQuery.restrict(
1820 06 Feb 13 olle 292       Restrictions.or(          
1820 06 Feb 13 olle 293         Subtype.LYSATE.restriction(dc, null),
1820 06 Feb 13 olle 294         Subtype.DNA.restriction(dc, null),
1820 06 Feb 13 olle 295         Subtype.RNA.restriction(dc, null),
1820 06 Feb 13 olle 296         Subtype.RNAQC.restriction(dc, null)
1820 06 Feb 13 olle 297       ));
1820 06 Feb 13 olle 298     extractQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2608 28 Aug 14 nicklas 299     if (site != null)
2608 28 Aug 14 nicklas 300     {
2608 28 Aug 14 nicklas 301       // Restrict by site
2608 28 Aug 14 nicklas 302       extractQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(site.getPrefix() + "%")));
2608 28 Aug 14 nicklas 303     }
1820 06 Feb 13 olle 304     extractQuery.order(Orders.asc(Hql.property("name")));
1820 06 Feb 13 olle 305     extractQuery.order(Orders.asc(Hql.property("ce", "eventDate")));
1820 06 Feb 13 olle 306     extractQuery.setCacheResult(true);
3907 29 Apr 16 nicklas 307     
3907 29 Apr 16 nicklas 308     // Count items
3907 29 Apr 16 nicklas 309     long totalCount = sampleQuery.count(dc);
3907 29 Apr 16 nicklas 310     totalCount += extractQuery.count(dc);
3907 29 Apr 16 nicklas 311     int count = 0;
3907 29 Apr 16 nicklas 312     
1820 06 Feb 13 olle 313     // Store samples that should be processed for report table in list
1820 06 Feb 13 olle 314     ItemSubtype subtypeSpecimen = Subtype.SPECIMEN.load(dc);
1820 06 Feb 13 olle 315     ItemSubtype subtypeHistology = Subtype.HISTOLOGY.load(dc);
1820 06 Feb 13 olle 316     ItemSubtype subtypeLysate = Subtype.LYSATE.load(dc);
1820 06 Feb 13 olle 317     ItemSubtype subtypeDna = Subtype.DNA.load(dc);
1820 06 Feb 13 olle 318     ItemSubtype subtypeRna = Subtype.RNA.load(dc);
1820 06 Feb 13 olle 319     ItemSubtype subtypeRnaQc = Subtype.RNAQC.load(dc);
1820 06 Feb 13 olle 320     Date date = null;
1858 19 Feb 13 nicklas 321     // Converter to check timestamps against midnight: 00:00:00
7024 07 Feb 23 nicklas 322     DateToStringConverter timeConverter = new DateToStringConverter(FastDateFormat.getInstance("HH:mm:ss"));
1855 18 Feb 13 olle 323     
1820 06 Feb 13 olle 324     // Use stored annotation snapshots for performance reasons
1820 06 Feb 13 olle 325     SnapshotManager manager = getSnapshotManager();
1820 06 Feb 13 olle 326     // Store samples with original quantity > 0 and with no special biopsy type
3907 29 Apr 16 nicklas 327     Iterator<Sample> samples = sampleQuery.iterate(dc);
3907 29 Apr 16 nicklas 328     while (samples.hasNext())
1820 06 Feb 13 olle 329     {
3907 29 Apr 16 nicklas 330       if (count % 100 == 0)
3907 29 Apr 16 nicklas 331       {
3907 29 Apr 16 nicklas 332         progress.display(5 + (int)((90 * count) / totalCount), 
3907 29 Apr 16 nicklas 333           "Processing " + Reggie.formatCount(count) + " of " + Reggie.formatCount(totalCount) + " items");
3907 29 Apr 16 nicklas 334       }
3907 29 Apr 16 nicklas 335       count++;
3907 29 Apr 16 nicklas 336
3907 29 Apr 16 nicklas 337       Sample sample = samples.next();
3907 29 Apr 16 nicklas 338       allSamples.add(sample);
3907 29 Apr 16 nicklas 339       
2608 28 Aug 14 nicklas 340       ItemSubtype subtype = sample.getItemSubtype();
2608 28 Aug 14 nicklas 341       if (subtypeHistology.equals(subtype))
1855 18 Feb 13 olle 342       {
2608 28 Aug 14 nicklas 343         sampleHistologyList.add(sample);
2608 28 Aug 14 nicklas 344         Date samplingDate = (Date) Annotationtype.SAMPLING_DATETIME.getAnnotationValue(dc, manager, sample);
2608 28 Aug 14 nicklas 345         sampleIdSamplingDateHashMap.put(sample.getId(), samplingDate);        
1855 18 Feb 13 olle 346       }
2608 28 Aug 14 nicklas 347       
2608 28 Aug 14 nicklas 348       if (subtypeSpecimen.equals(subtype))
1820 06 Feb 13 olle 349       {
2608 28 Aug 14 nicklas 350         // Get minutes to RNAlater
2608 28 Aug 14 nicklas 351         Date samplingDate = (Date) Annotationtype.SAMPLING_DATETIME.getAnnotationValue(dc, manager, sample);
2608 28 Aug 14 nicklas 352         Date rnaLaterDate = (Date) Annotationtype.RNALATER_DATETIME.getAnnotationValue(dc, manager, sample);
2608 28 Aug 14 nicklas 353         sampleIdSamplingDateHashMap.put(sample.getId(), samplingDate);        
2608 28 Aug 14 nicklas 354         sampleIdRnaLaterDateHashMap.put(sample.getId(), rnaLaterDate);        
2608 28 Aug 14 nicklas 355         if (samplingDate != null && rnaLaterDate != null)
1820 06 Feb 13 olle 356         {
2608 28 Aug 14 nicklas 357           // Check that time of day is not 00:00:00
2608 28 Aug 14 nicklas 358           String samplingTimeOfDayStr = timeConverter.convert(samplingDate);
2608 28 Aug 14 nicklas 359           String rnaLaterTimeOfDayStr = timeConverter.convert(rnaLaterDate);
2608 28 Aug 14 nicklas 360           if (!samplingTimeOfDayStr.equals("00:00:00") && !rnaLaterTimeOfDayStr.equals("00:00:00"))
1820 06 Feb 13 olle 361           {
2608 28 Aug 14 nicklas 362             long timeToRnaLaterInMs = rnaLaterDate.getTime() - samplingDate.getTime();
2608 28 Aug 14 nicklas 363             long minToRnaLater = timeToRnaLaterInMs/60000;
2608 28 Aug 14 nicklas 364             sampleIdMinToRnaLaterHashMap.put(sample.getId(), minToRnaLater);
2608 28 Aug 14 nicklas 365             // Store samples with negative or zero min to RNAlater
2608 28 Aug 14 nicklas 366             if (minToRnaLater < 0)
1820 06 Feb 13 olle 367             {
2608 28 Aug 14 nicklas 368               sampleNegativeMinToRnaLaterList.add(sample);
1820 06 Feb 13 olle 369             }
2608 28 Aug 14 nicklas 370             else if (minToRnaLater == 0)
2608 28 Aug 14 nicklas 371             {
2608 28 Aug 14 nicklas 372               sampleZeroMinToRnaLaterList.add(sample);
2608 28 Aug 14 nicklas 373             }
1820 06 Feb 13 olle 374           }
1820 06 Feb 13 olle 375         }
1820 06 Feb 13 olle 376       }
1820 06 Feb 13 olle 377     }
2608 28 Aug 14 nicklas 378     
3907 29 Apr 16 nicklas 379     Iterator<Extract> extracts = extractQuery.iterate(dc);
3907 29 Apr 16 nicklas 380     while (extracts.hasNext())
1820 06 Feb 13 olle 381     {
3907 29 Apr 16 nicklas 382       if (count % 100 == 0)
3907 29 Apr 16 nicklas 383       {
3907 29 Apr 16 nicklas 384         progress.display(5 + (int)((90 * count) / totalCount), 
3907 29 Apr 16 nicklas 385           "Processing " + Reggie.formatCount(count) + " of " + Reggie.formatCount(totalCount) + " items");
3907 29 Apr 16 nicklas 386       }
3907 29 Apr 16 nicklas 387       count++;
3907 29 Apr 16 nicklas 388
3907 29 Apr 16 nicklas 389       Extract extract = extracts.next();
2608 28 Aug 14 nicklas 390       ItemSubtype subtype = extract.getItemSubtype();
2608 28 Aug 14 nicklas 391       if (subtypeLysate.equals(subtype))
1820 06 Feb 13 olle 392       {
2608 28 Aug 14 nicklas 393         Sample specimen = (Sample)extract.getParent();
2608 28 Aug 14 nicklas 394         if (allSamples.contains(specimen))
1820 06 Feb 13 olle 395         {
3907 29 Apr 16 nicklas 396           allLysates.add(extract);
2608 28 Aug 14 nicklas 397           // Update tissue quantity used (several extracts may be made from the same parent sample)
2608 28 Aug 14 nicklas 398           Float quantityTissueUsed = extract.getCreationEvent().getUsedQuantity(specimen);
2608 28 Aug 14 nicklas 399           updateSampleIdTissueQuantityUsedHashMap(specimen, quantityTissueUsed);
1820 06 Feb 13 olle 400         }
1820 06 Feb 13 olle 401       }
3907 29 Apr 16 nicklas 402       else if (subtypeDna.equals(subtype))
1820 06 Feb 13 olle 403       {
1914 21 Mar 13 nicklas 404         BioMaterial dnaParent = extract.getParent();
3907 29 Apr 16 nicklas 405         if (allLysates.contains(dnaParent))
1820 06 Feb 13 olle 406         {
1914 21 Mar 13 nicklas 407           Extract lysate = (Extract)dnaParent;
1914 21 Mar 13 nicklas 408           extractDnaList.add(extract);
1914 21 Mar 13 nicklas 409           date = (Date) Annotationtype.QIACUBE_DATE.getAnnotationValue(dc, manager, extract);
1914 21 Mar 13 nicklas 410           extractIdQiaCubeDateHashMap.put(extract.getId(), date);
1914 21 Mar 13 nicklas 411           Sample sample = (Sample) lysate.getParent();
1914 21 Mar 13 nicklas 412           sampleIdQiaCubeDateHashMap.put(sample.getId(), date);
1914 21 Mar 13 nicklas 413           // Store sample id for DNA yield calculation
1914 21 Mar 13 nicklas 414           extractIdSampleIdHashMap.put(extract.getId(), sample.getId());
1820 06 Feb 13 olle 415         }
1820 06 Feb 13 olle 416       }
2608 28 Aug 14 nicklas 417       else if (subtypeRna.equals(subtype))
1820 06 Feb 13 olle 418       {
1914 21 Mar 13 nicklas 419         BioMaterial rnaParent = extract.getParent();
3907 29 Apr 16 nicklas 420         if (allLysates.contains(rnaParent))
1820 06 Feb 13 olle 421         {
1914 21 Mar 13 nicklas 422           Extract lysate = (Extract)rnaParent;
1914 21 Mar 13 nicklas 423           extractRnaList.add(extract);
1914 21 Mar 13 nicklas 424           date = (Date) Annotationtype.QIACUBE_DATE.getAnnotationValue(dc, manager, extract);
1914 21 Mar 13 nicklas 425           extractIdQiaCubeDateHashMap.put(extract.getId(), date);
1914 21 Mar 13 nicklas 426           Sample sample = (Sample) lysate.getParent();
1914 21 Mar 13 nicklas 427           sampleIdQiaCubeDateHashMap.put(sample.getId(), date);
1914 21 Mar 13 nicklas 428           // Store sample id for RNA yield calculation
1914 21 Mar 13 nicklas 429           extractIdSampleIdHashMap.put(extract.getId(), sample.getId());
1820 06 Feb 13 olle 430         }
1820 06 Feb 13 olle 431       }
2608 28 Aug 14 nicklas 432       else if (subtypeRnaQc.equals(subtype))
1820 06 Feb 13 olle 433       {
3907 29 Apr 16 nicklas 434         Extract rnaQcParentExtract = (Extract)extract.getParent();
1842 14 Feb 13 olle 435         Integer sampleId = extractIdSampleIdHashMap.get(rnaQcParentExtract.getId());
3907 29 Apr 16 nicklas 436         
3907 29 Apr 16 nicklas 437         // RNAQC extract are traced back to the grand parent sample they originate from.
3907 29 Apr 16 nicklas 438         // Only one RNAQC value (RQS or RIN) per sample is used.
3907 29 Apr 16 nicklas 439         // If a valid RQS value exists for a sample, it is used, otherwise a valid RIN value.
3907 29 Apr 16 nicklas 440         // For a RQS or RIN value to be valid, it should be > 0 (-100 is used as flag for bad data).
3907 29 Apr 16 nicklas 441         // If several valid RQS or RIN values exist for a sample, the first to occur is used.
3907 29 Apr 16 nicklas 442         
3907 29 Apr 16 nicklas 443         Float extractRqs = (Float) Annotationtype.CA_RQS.getAnnotationValue(dc, manager, extract);
3907 29 Apr 16 nicklas 444         Float extractRin = (Float) Annotationtype.BA_RIN.getAnnotationValue(dc, manager, extract);
3907 29 Apr 16 nicklas 445
3907 29 Apr 16 nicklas 446         // Check if RQS value exists and is > 0 (-100 is used as flag for bad data) 
3907 29 Apr 16 nicklas 447         if (extractRqs != null && extractRqs > 0.0f)
1820 06 Feb 13 olle 448         {
3907 29 Apr 16 nicklas 449           // Valid RQS value for the RNAQC extract
3907 29 Apr 16 nicklas 450           // Check if a valid RNAQC values already is stored for the sample
3907 29 Apr 16 nicklas 451           if (sampleId != null && !rnaQcGrandParentSampleIds.contains(sampleId))
3907 29 Apr 16 nicklas 452           {
3907 29 Apr 16 nicklas 453             extractRnaQcList.add(extract);
3907 29 Apr 16 nicklas 454             extractIdRqsHashMap.put(extract.getId(), extractRqs);
3907 29 Apr 16 nicklas 455             // Use the parent RNA QiaCube date
3907 29 Apr 16 nicklas 456             date = (Date) Annotationtype.QIACUBE_DATE.getAnnotationValue(dc, manager, rnaQcParentExtract);
3907 29 Apr 16 nicklas 457             extractIdQiaCubeDateHashMap.put(extract.getId(), date);
3907 29 Apr 16 nicklas 458             // Add id of grand parent sample to list, in order to check
3907 29 Apr 16 nicklas 459             // that not another RNAQC extract from the same sample is used
3907 29 Apr 16 nicklas 460             rnaQcGrandParentSampleIds.add(sampleId);
3907 29 Apr 16 nicklas 461           }
1820 06 Feb 13 olle 462         }
3907 29 Apr 16 nicklas 463         else if (extractRin != null && extractRin > 0.0f)
1842 14 Feb 13 olle 464         {
3907 29 Apr 16 nicklas 465           // Check if a valid RNAQC values already is stored for the sample
3907 29 Apr 16 nicklas 466           if (sampleId != null && !rnaQcGrandParentSampleIds.contains(sampleId))
3907 29 Apr 16 nicklas 467           {
3907 29 Apr 16 nicklas 468             extractRnaQcList.add(extract);
3907 29 Apr 16 nicklas 469             extractIdRinHashMap.put(extract.getId(), extractRin);
3907 29 Apr 16 nicklas 470             // Use the parent RNA QiaCube date
3907 29 Apr 16 nicklas 471             date = (Date) Annotationtype.QIACUBE_DATE.getAnnotationValue(dc, manager, rnaQcParentExtract);
3907 29 Apr 16 nicklas 472             extractIdQiaCubeDateHashMap.put(extract.getId(), date);
3907 29 Apr 16 nicklas 473             // Add id of grand parent sample to list, in order to check
3907 29 Apr 16 nicklas 474             // that not another RNAQC extract from the same sample is used
3907 29 Apr 16 nicklas 475             rnaQcGrandParentSampleIds.add(sampleId);
3907 29 Apr 16 nicklas 476           }
1842 14 Feb 13 olle 477         }
1842 14 Feb 13 olle 478       }
1842 14 Feb 13 olle 479     }
3907 29 Apr 16 nicklas 480     
3907 29 Apr 16 nicklas 481     progress.display(98, "Processed " + count + " items. Generating plots...");
3907 29 Apr 16 nicklas 482
1820 06 Feb 13 olle 483     // Create list of view types for plots
1820 06 Feb 13 olle 484     List<String> viewTypeList = new ArrayList<String>();
1820 06 Feb 13 olle 485     if (viewType.equals(quarterMonthView))
1820 06 Feb 13 olle 486     {
1820 06 Feb 13 olle 487       // Create plots for quarter and month
2611 29 Aug 14 nicklas 488       viewTypeList.add(ReportTableUtil.quarterView);
2611 29 Aug 14 nicklas 489       viewTypeList.add(ReportTableUtil.monthView);
1820 06 Feb 13 olle 490     }
1820 06 Feb 13 olle 491     else
1820 06 Feb 13 olle 492     {
1820 06 Feb 13 olle 493       // Create plot(s) for one view type
1820 06 Feb 13 olle 494       viewTypeList.add(viewType);
1820 06 Feb 13 olle 495     }
1820 06 Feb 13 olle 496     // Create list of chart variants for plots
1820 06 Feb 13 olle 497     List<String> chartVariantList;
1820 06 Feb 13 olle 498     if (chartVariant.equals(allCharts))
1820 06 Feb 13 olle 499     {
1820 06 Feb 13 olle 500       // Create several plots
1820 06 Feb 13 olle 501       chartVariantList = getChartVariantList();
1820 06 Feb 13 olle 502     }
1820 06 Feb 13 olle 503     else
1820 06 Feb 13 olle 504     {
1820 06 Feb 13 olle 505       // Create one plot
1820 06 Feb 13 olle 506       chartVariantList = new ArrayList<String>();
1820 06 Feb 13 olle 507       chartVariantList.add(chartVariant);
1820 06 Feb 13 olle 508     }
1820 06 Feb 13 olle 509     // Create JSON array for plot data
1820 06 Feb 13 olle 510     JSONArray jsonStatisticsPlotArray = new JSONArray();
1820 06 Feb 13 olle 511     // Create plot statistics data and put in JSON statistics plot array
1820 06 Feb 13 olle 512     for (String vType: viewTypeList)
1820 06 Feb 13 olle 513     {
1820 06 Feb 13 olle 514       for (String cVariant: chartVariantList)
1820 06 Feb 13 olle 515       {
1820 06 Feb 13 olle 516         // Get JSON statistics data
2608 28 Aug 14 nicklas 517         JSONObject plotJsonData = createJsonPlot(cVariant, startDate, endDate, vType, site);
1825 07 Feb 13 olle 518         plotJsonData = addExtraInfo(plotJsonData, cVariant);
1820 06 Feb 13 olle 519         JSONObject plotJsonDataContainer = new JSONObject();
2608 28 Aug 14 nicklas 520         plotJsonDataContainer.put("site", site == null ? null : site.asJSONObject());
1820 06 Feb 13 olle 521         plotJsonDataContainer.put("chartVariant", cVariant);
1820 06 Feb 13 olle 522         plotJsonDataContainer.put("viewType", vType);
1820 06 Feb 13 olle 523         plotJsonDataContainer.put("plotData", plotJsonData);
1820 06 Feb 13 olle 524         String optionalHeadline = "";
1820 06 Feb 13 olle 525         plotJsonDataContainer.put("optionalHeadline", optionalHeadline);
1820 06 Feb 13 olle 526         jsonStatisticsPlotArray.add(plotJsonDataContainer);
1820 06 Feb 13 olle 527       }
1820 06 Feb 13 olle 528     }
1820 06 Feb 13 olle 529     // Add JSON statistics plot array to report
1820 06 Feb 13 olle 530     jsonReport.put("plotStatistics", jsonStatisticsPlotArray);
1843 14 Feb 13 olle 531     // Appended info
1843 14 Feb 13 olle 532     String appendedInfoText = "";
1846 15 Feb 13 olle 533     // Add info on special samples if chart for min to RNAlater is selected
1843 14 Feb 13 olle 534     if (chartVariantList.contains(minutesToRnaLaterChart))
1843 14 Feb 13 olle 535     {
1851 18 Feb 13 nicklas 536       appendedInfoText += "<h2 class=\"pagebreak\">Appended Info</h2>";
1843 14 Feb 13 olle 537       appendedInfoText += "<br>";
1846 15 Feb 13 olle 538       appendedInfoText += createMinToRnaLaterAppendTextTable(dc, "Samples with negative min to RNAlater", sampleNegativeMinToRnaLaterList);
1843 14 Feb 13 olle 539       appendedInfoText += "<br>";
1846 15 Feb 13 olle 540       appendedInfoText += createMinToRnaLaterAppendTextTable(dc, "Samples with zero min to RNAlater", sampleZeroMinToRnaLaterList);
1846 15 Feb 13 olle 541       appendedInfoText += "<br>";
1843 14 Feb 13 olle 542     }
1843 14 Feb 13 olle 543     // Add JSON appended info to report
1843 14 Feb 13 olle 544     jsonReport.put("appendedInfo", appendedInfoText);
1820 06 Feb 13 olle 545     // Add other data to report
1820 06 Feb 13 olle 546     DateToStringConverter date2StringConverter = Reggie.CONVERTER_DATE_TO_STRING;
1820 06 Feb 13 olle 547     jsonReport.put("beginDate", date2StringConverter.convert(startDate));
1820 06 Feb 13 olle 548     jsonReport.put("endDate", date2StringConverter.convert(endDate));
1820 06 Feb 13 olle 549     //
1820 06 Feb 13 olle 550     json.put("report", jsonReport);
1820 06 Feb 13 olle 551     return json;
1820 06 Feb 13 olle 552   }
1820 06 Feb 13 olle 553
1846 15 Feb 13 olle 554   private String createMinToRnaLaterAppendTextTable(DbControl dc, String title, List<Sample> sampleList)
1846 15 Feb 13 olle 555   {
1846 15 Feb 13 olle 556     // Note: Generated HTML code refers to classes defined in resources/reggie.css
1846 15 Feb 13 olle 557     String text = "<table class='reporttable'>";
1846 15 Feb 13 olle 558     // Report header
1846 15 Feb 13 olle 559     text += "<tr>";
1846 15 Feb 13 olle 560     text += "<td class='reportheader' colspan='4'>" + title + "</td>";
1846 15 Feb 13 olle 561     text += "</tr>";
1846 15 Feb 13 olle 562     // Report header
1846 15 Feb 13 olle 563     text += "<tr>";
1846 15 Feb 13 olle 564     text += "<td class='reportsubheader'>Sample</td>";
1846 15 Feb 13 olle 565     text += "<td class='reportsubheader'>Sampling date</td>";
1846 15 Feb 13 olle 566     text += "<td class='reportsubheader'>RNAlater date</td>";
1915 21 Mar 13 nicklas 567     text += "<td class='reportsubheader noprint'>Case summary</td>";
1846 15 Feb 13 olle 568     text += "</tr>";
7024 07 Feb 23 nicklas 569     DateToStringConverter dateFormat = new DateToStringConverter(FastDateFormat.getInstance("yyyy-MM-dd HH:mm"));
1846 15 Feb 13 olle 570     for (Sample s: sampleList)
1846 15 Feb 13 olle 571     {
1846 15 Feb 13 olle 572       Date samplingDate = sampleIdSamplingDateHashMap.get(s.getId());
1846 15 Feb 13 olle 573       Date rnaLaterDate = sampleIdRnaLaterDateHashMap.get(s.getId());
1858 19 Feb 13 nicklas 574       String samplingDateStr = dateFormat.convert(samplingDate);
1858 19 Feb 13 nicklas 575       String rnaLaterDateStr = dateFormat.convert(rnaLaterDate);
5019 10 Oct 18 nicklas 576       String caseSummaryButtonCode = createCaseSummaryButton(dc, s.getName());
1846 15 Feb 13 olle 577       text += "<tr>";
1846 15 Feb 13 olle 578       text += "<td class='reportdata'>" + s.getName() + "</td>";
1846 15 Feb 13 olle 579       text += "<td class='reportdata'>" + samplingDateStr + "</td>";
1846 15 Feb 13 olle 580       text += "<td class='reportdata'>" + rnaLaterDateStr + "</td>";
1915 21 Mar 13 nicklas 581       text += "<td class='reportdata noprint'>" + caseSummaryButtonCode + "</td>";
1846 15 Feb 13 olle 582       text += "</tr>";
1846 15 Feb 13 olle 583     }
1846 15 Feb 13 olle 584     text += "</table>";
1846 15 Feb 13 olle 585     return text;
1846 15 Feb 13 olle 586   }
1846 15 Feb 13 olle 587
1846 15 Feb 13 olle 588   private String createCaseSummaryButton(DbControl dc, String caseName)
1846 15 Feb 13 olle 589   {
1846 15 Feb 13 olle 590     String sessionId = dc.getSessionControl().getId();
2608 28 Aug 14 nicklas 591     caseName = HTML.encodeTags(caseName);
5019 10 Oct 18 nicklas 592     String htmlStr ="<div class=\"link case-summary\" data-name=\""+caseName + "\" title=\"Reggie: Show summary of case #" + caseName + "\"><img src=\"../images/case_summary.png\">&nbsp;" + caseName + "</div>";
2608 28 Aug 14 nicklas 593     return htmlStr;
1846 15 Feb 13 olle 594   }
1846 15 Feb 13 olle 595
2608 28 Aug 14 nicklas 596   private JSONObject createJsonPlot(String chartVariant, Date startDate, Date endDate, String viewType, Site site)
1820 06 Feb 13 olle 597     throws ServletException, IOException 
1820 06 Feb 13 olle 598   {
1820 06 Feb 13 olle 599     // Get JSON statistics data
2608 28 Aug 14 nicklas 600     String chartHeaderTitle = fetchChartHeaderTitle(chartVariant, viewType, site);
1820 06 Feb 13 olle 601     String chartTitle = fetchChartTitle(chartVariant);
1820 06 Feb 13 olle 602     String chartYAxisTitle = fetchChartYAxisTitle(chartVariant);
1820 06 Feb 13 olle 603     // Get HashMap with lists of samples for chosen time periods 
1820 06 Feb 13 olle 604     HashMap<String,List<Float>> periodStringFloatListHashMap = createPeriodStringFloatListHashMap(chartVariant, startDate, endDate, viewType);
1820 06 Feb 13 olle 605     JSONObject jsonPlotStatistics = createJSONPlotStatistics(chartVariant, chartHeaderTitle, chartTitle, chartYAxisTitle, periodStringFloatListHashMap, viewType);
1820 06 Feb 13 olle 606     return jsonPlotStatistics;
1820 06 Feb 13 olle 607   }
1820 06 Feb 13 olle 608
1820 06 Feb 13 olle 609   private JSONObject createJSONPlotStatistics(String chartVariant, String headerTitle, String title, String variableTitle, HashMap<String,List<Float>> periodStringFloatListHashMap, String viewType)
1820 06 Feb 13 olle 610     throws ServletException, IOException 
1820 06 Feb 13 olle 611   {
1820 06 Feb 13 olle 612     // Calculate statistics for all samples
1820 06 Feb 13 olle 613     List<Float> floatList = singleFloatList(periodStringFloatListHashMap);
1820 06 Feb 13 olle 614     int numItems = floatList.size();
1820 06 Feb 13 olle 615     Float floatMin = calculateMinValue(floatList);
1820 06 Feb 13 olle 616     Float floatMax = calculateMaxValue(floatList);
1820 06 Feb 13 olle 617     Float floatMean = calculateMeanValue(floatList);
1820 06 Feb 13 olle 618     Float floatSDev = calculateSDev(floatList);
1820 06 Feb 13 olle 619     Collections.sort(floatList);
1820 06 Feb 13 olle 620     Float floatPct25 = calculatePercentile(floatList, 0.25f);
1820 06 Feb 13 olle 621     Float floatPct50 = calculatePercentile(floatList, 0.50f);
1820 06 Feb 13 olle 622     Float floatPct75 = calculatePercentile(floatList, 0.75f);
2008 19 Jun 13 olle 623     int localNumberOfDecimals = numberOfDecimals;
2008 19 Jun 13 olle 624     if (floatPct25 != null && floatPct25 < 1)
2008 19 Jun 13 olle 625     {
2008 19 Jun 13 olle 626       localNumberOfDecimals = numberOfDecimals + 1;
2008 19 Jun 13 olle 627     }
1820 06 Feb 13 olle 628     // Create JSON object with sample statistics
1820 06 Feb 13 olle 629     JSONObject jsonStat = new JSONObject();
1820 06 Feb 13 olle 630     jsonStat.put("headerTitleTop", headerTitle);
1820 06 Feb 13 olle 631     jsonStat.put("titleTop", title);
1820 06 Feb 13 olle 632     jsonStat.put("titleBottom", "");
1820 06 Feb 13 olle 633     jsonStat.put("subTitleRight", "n = " + numItems);
1857 19 Feb 13 nicklas 634     jsonStat.put("subTitleLeft01", "mean, " + Values.formatNumber(floatMean, localNumberOfDecimals));
1857 19 Feb 13 nicklas 635     jsonStat.put("subTitleLeft02", "sd, " + Values.formatNumber(floatSDev, localNumberOfDecimals));
1857 19 Feb 13 nicklas 636     jsonStat.put("subTitleLeft03", "range, " + Values.formatNumber(floatMin, localNumberOfDecimals) + ", " + Values.formatNumber(floatMax, localNumberOfDecimals));
1820 06 Feb 13 olle 637     jsonStat.put("yAxisTitleLeft", variableTitle);
1820 06 Feb 13 olle 638     jsonStat.put("yAxisTitleRight", "");
1820 06 Feb 13 olle 639     // Create JSON array of sample statistics for time periods
1820 06 Feb 13 olle 640     JSONArray jsonPeriodPercentilesArray = new JSONArray();
1820 06 Feb 13 olle 641     List<String> periodList = new ArrayList<String>();
1820 06 Feb 13 olle 642     for (String period: periodStringFloatListHashMap.keySet())
1820 06 Feb 13 olle 643     {
1820 06 Feb 13 olle 644       periodList.add(period);
1820 06 Feb 13 olle 645     }
1820 06 Feb 13 olle 646     Collections.sort(periodList);
1820 06 Feb 13 olle 647     for (String period: periodList)
1820 06 Feb 13 olle 648     {
1820 06 Feb 13 olle 649       if (periodStringFloatListHashMap.get(period).size() >= minItemsForStatisticsCalculation)
1820 06 Feb 13 olle 650       {
1820 06 Feb 13 olle 651         List<Float> periodFloatList = periodStringFloatListHashMap.get(period);
1820 06 Feb 13 olle 652         // Get name of time period in standard format for plot
1820 06 Feb 13 olle 653         String periodName = fetchPeriodNameForPlot(period, viewType);
1820 06 Feb 13 olle 654         JSONObject jsonPeriodData = createSamplePeriodJSONStatistics(periodFloatList, periodName);
1820 06 Feb 13 olle 655         jsonPeriodPercentilesArray.add(jsonPeriodData);
1820 06 Feb 13 olle 656       }
1820 06 Feb 13 olle 657     }
1820 06 Feb 13 olle 658     jsonStat.put("percentileData", jsonPeriodPercentilesArray);
1820 06 Feb 13 olle 659     // Create JSON array of percentile data for all samples
1820 06 Feb 13 olle 660     JSONArray jsonPercentilesArray = new JSONArray();
1857 19 Feb 13 nicklas 661     JSONObject jsonPct25 = createValueWithText(floatPct25, localNumberOfDecimals);
1820 06 Feb 13 olle 662     jsonPercentilesArray.add(jsonPct25);
1857 19 Feb 13 nicklas 663     JSONObject jsonPct50 = createValueWithText(floatPct50, localNumberOfDecimals);
1820 06 Feb 13 olle 664     jsonPercentilesArray.add(jsonPct50);
1857 19 Feb 13 nicklas 665     JSONObject jsonPct75 = createValueWithText(floatPct75, localNumberOfDecimals);
1820 06 Feb 13 olle 666     jsonPercentilesArray.add(jsonPct75);
1820 06 Feb 13 olle 667     jsonStat.put("valueGuideLinesY", jsonPercentilesArray);
1820 06 Feb 13 olle 668     return jsonStat;        
1820 06 Feb 13 olle 669   }
1820 06 Feb 13 olle 670
1845 15 Feb 13 olle 671   private JSONObject createValueWithText(Float value, int numberOfDecimalsShown)
1845 15 Feb 13 olle 672   {
1845 15 Feb 13 olle 673     if (value == null)
1845 15 Feb 13 olle 674     {
1845 15 Feb 13 olle 675       return null;
1845 15 Feb 13 olle 676     }
1845 15 Feb 13 olle 677     JSONObject jsonValueWithText = createValueWithText(value, Values.formatNumber(value, numberOfDecimalsShown));
1845 15 Feb 13 olle 678     return jsonValueWithText;
1845 15 Feb 13 olle 679   }
1845 15 Feb 13 olle 680
1845 15 Feb 13 olle 681   private JSONObject createValueWithText(Float value, String text)
1845 15 Feb 13 olle 682   {
1845 15 Feb 13 olle 683     if (value == null)
1845 15 Feb 13 olle 684     {
1845 15 Feb 13 olle 685       return null;
1845 15 Feb 13 olle 686     }
1845 15 Feb 13 olle 687     JSONObject jsonValueWithText = new JSONObject();
1845 15 Feb 13 olle 688     jsonValueWithText.put("value", value);
1845 15 Feb 13 olle 689     jsonValueWithText.put("text", text);    
1845 15 Feb 13 olle 690     return jsonValueWithText;
1845 15 Feb 13 olle 691   }
1845 15 Feb 13 olle 692
1820 06 Feb 13 olle 693   private JSONObject createSamplePeriodJSONStatistics(List<Float> floatList, String periodName)
1820 06 Feb 13 olle 694       throws ServletException, IOException 
1820 06 Feb 13 olle 695     {  
1820 06 Feb 13 olle 696       // Calculate statistics for samples
1820 06 Feb 13 olle 697       int numItems = floatList.size();
1820 06 Feb 13 olle 698       Collections.sort(floatList);
1820 06 Feb 13 olle 699       //Float floatPct05 = calculatePercentile(floatList, 0.05f);
1820 06 Feb 13 olle 700       Float floatPct25 = calculatePercentile(floatList, 0.25f);
1820 06 Feb 13 olle 701       Float floatPct50 = calculatePercentile(floatList, 0.50f);
1820 06 Feb 13 olle 702       Float floatPct75 = calculatePercentile(floatList, 0.75f);
1820 06 Feb 13 olle 703       //Float floatPct95 = calculatePercentile(floatList, 0.95f);
1820 06 Feb 13 olle 704       // Inter-percentile range ipr = pct75 - pct25
1820 06 Feb 13 olle 705       // Calculate whisker values as lowest and highest data values within coef*ipr from box ends
1820 06 Feb 13 olle 706       float coef = 1.5f;
1820 06 Feb 13 olle 707       Float w1 = calculateBoxPlotWhiskerValue(floatList, floatPct25, floatPct75, coef, "lower");
1820 06 Feb 13 olle 708       Float w2 = calculateBoxPlotWhiskerValue(floatList, floatPct25, floatPct75, coef, "upper");
1820 06 Feb 13 olle 709       // Create JSON object with sample statistics for period
1820 06 Feb 13 olle 710       JSONObject jsonStat = new JSONObject();
1820 06 Feb 13 olle 711       jsonStat.put("name", periodName);
1820 06 Feb 13 olle 712       jsonStat.put("numItems", numItems);
1820 06 Feb 13 olle 713       jsonStat.put("v1", w1);
1820 06 Feb 13 olle 714       jsonStat.put("v2", floatPct25);
1820 06 Feb 13 olle 715       jsonStat.put("v3", floatPct50);
1820 06 Feb 13 olle 716       jsonStat.put("v4", floatPct75);
1820 06 Feb 13 olle 717       jsonStat.put("v5", w2);
1820 06 Feb 13 olle 718       return jsonStat;        
1820 06 Feb 13 olle 719     }
1820 06 Feb 13 olle 720
1820 06 Feb 13 olle 721   /**
1820 06 Feb 13 olle 722    *  Returns a period string intended for use as label in box plot.
1820 06 Feb 13 olle 723    *  The period string will be modified as follows for different view types:<br>
1820 06 Feb 13 olle 724    *  Year view:    yyyy  ->  yyyy    (no change)<br>
1820 06 Feb 13 olle 725    *  Quarter view: yyyyq  -> yyyy-Qq (e.g. 20123  -> 2012-Q3)<br>
1820 06 Feb 13 olle 726    *  Month view:   yyyymm -> yyyy-mm (e.g. 201203 -> 2012-03)<br>
1820 06 Feb 13 olle 727    *  Week view:    yyyyww -> yyyy-ww (e.g. 201203 -> 2012-03)<br>
1820 06 Feb 13 olle 728    * 
1820 06 Feb 13 olle 729    *  @param period String The period string in pure number format.
1820 06 Feb 13 olle 730    *  @param viewType String The view type.
1820 06 Feb 13 olle 731    *  @return String A period string intended for use as label in box plot.
1820 06 Feb 13 olle 732    */
1820 06 Feb 13 olle 733   private String fetchPeriodNameForPlot(String period, String viewType)
1820 06 Feb 13 olle 734   {
1820 06 Feb 13 olle 735     if (period == null || period.length() < 4)
1820 06 Feb 13 olle 736     {
1820 06 Feb 13 olle 737       return period;
1820 06 Feb 13 olle 738     }
1820 06 Feb 13 olle 739     String yearStr = period.substring(0,4);
1820 06 Feb 13 olle 740     String residueStr = period.substring(4);
1820 06 Feb 13 olle 741     // Add year string
1820 06 Feb 13 olle 742     String periodName = yearStr;
1820 06 Feb 13 olle 743     if (residueStr.length() > 0)
1820 06 Feb 13 olle 744     {
1820 06 Feb 13 olle 745       // Add hyphen after year string
1820 06 Feb 13 olle 746       periodName += "-";
2611 29 Aug 14 nicklas 747       if (viewType.equals(ReportTableUtil.quarterView))
1820 06 Feb 13 olle 748       {
1820 06 Feb 13 olle 749         // Add 'Q' after year string
1820 06 Feb 13 olle 750         periodName += "Q";
1820 06 Feb 13 olle 751       }
1820 06 Feb 13 olle 752       // Add residue string (quarter, month, or week string)
1820 06 Feb 13 olle 753       periodName += residueStr;
1820 06 Feb 13 olle 754     }
1820 06 Feb 13 olle 755     return periodName;
1820 06 Feb 13 olle 756   }
1820 06 Feb 13 olle 757
1820 06 Feb 13 olle 758   private HashMap<String, List<Float>> createPeriodStringFloatListHashMap(String chartVariant, Date startDate, Date endDate, String viewType)
1820 06 Feb 13 olle 759     throws ServletException, IOException 
1820 06 Feb 13 olle 760   {  
1820 06 Feb 13 olle 761     // Create HashMap to keep track of values for each time period
1820 06 Feb 13 olle 762     HashMap<String, List<Float>> periodStringFloatListHashMap = new HashMap<String, List<Float>>();
1820 06 Feb 13 olle 763
1820 06 Feb 13 olle 764     if (chartVariant.equals(originalQuantityTissueChart))
1820 06 Feb 13 olle 765     {
2608 28 Aug 14 nicklas 766       for (Sample s: allSamples)
1820 06 Feb 13 olle 767       {
1840 13 Feb 13 olle 768         // Use QiaCube date of extract from lysate from sample
1820 06 Feb 13 olle 769         Date date = sampleIdQiaCubeDateHashMap.get(s.getId());              
1820 06 Feb 13 olle 770         if (date != null)
1820 06 Feb 13 olle 771         {
1820 06 Feb 13 olle 772           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 773               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 774           {
1820 06 Feb 13 olle 775             // Get current period
1820 06 Feb 13 olle 776             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 777             // Update period value hash map
1820 06 Feb 13 olle 778             Float value = null;
1820 06 Feb 13 olle 779             // Get value in mg (stored in microgram)
1820 06 Feb 13 olle 780             value = s.getOriginalQuantity()/1000.0f;
1820 06 Feb 13 olle 781             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 782           }
1820 06 Feb 13 olle 783         }
1820 06 Feb 13 olle 784       }
1820 06 Feb 13 olle 785     }
1820 06 Feb 13 olle 786     else if (chartVariant.equals(quantityTissueUsedChart))
1820 06 Feb 13 olle 787     {
2608 28 Aug 14 nicklas 788       for (Sample s: allSamples)
1820 06 Feb 13 olle 789       {
1840 13 Feb 13 olle 790         // Use QiaCube date of extract from lysate from sample
1820 06 Feb 13 olle 791         Date date = sampleIdQiaCubeDateHashMap.get(s.getId());              
1820 06 Feb 13 olle 792         if (date != null)
1820 06 Feb 13 olle 793         {
1820 06 Feb 13 olle 794           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 795               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 796           {
1820 06 Feb 13 olle 797             // Get current period
1820 06 Feb 13 olle 798             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 799             // Update period value hash map
1820 06 Feb 13 olle 800             Float value = null;
1820 06 Feb 13 olle 801             // Get value in mg (stored in microgram)
1820 06 Feb 13 olle 802             value = getSampleIdTissueQuantityUsedHashMap().get(s.getId());
1820 06 Feb 13 olle 803             if (value != null)
1820 06 Feb 13 olle 804             {
1820 06 Feb 13 olle 805               value /= 1000.0f;
1820 06 Feb 13 olle 806             }
1820 06 Feb 13 olle 807             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 808           }
1820 06 Feb 13 olle 809         }
1820 06 Feb 13 olle 810       }
1820 06 Feb 13 olle 811     }
1820 06 Feb 13 olle 812     else if (chartVariant.equals(remainingQuantityForScanBSpecimenChart))
1820 06 Feb 13 olle 813     {
1825 07 Feb 13 olle 814       setNumRemainingTissueItemsGT1Mg(0);
2608 28 Aug 14 nicklas 815       for (Sample s: allSamples)
1820 06 Feb 13 olle 816       {
1840 13 Feb 13 olle 817         // Use QiaCube date of extract from lysate from sample
1820 06 Feb 13 olle 818         Date date = sampleIdQiaCubeDateHashMap.get(s.getId());              
1820 06 Feb 13 olle 819         if (date != null)
1820 06 Feb 13 olle 820         {
1820 06 Feb 13 olle 821           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 822               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 823           {
1820 06 Feb 13 olle 824             // Get current period
1820 06 Feb 13 olle 825             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 826             // Update period value hash map
1820 06 Feb 13 olle 827             Float value = null;
1820 06 Feb 13 olle 828             // Get value in mg (stored in microgram)
1820 06 Feb 13 olle 829             value = s.getRemainingQuantity()/1000.0f;
1825 07 Feb 13 olle 830             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);
1825 07 Feb 13 olle 831             // Update counter for items > 1 mg
1825 07 Feb 13 olle 832             if (value > 1.0f)
1825 07 Feb 13 olle 833             {
1825 07 Feb 13 olle 834               setNumRemainingTissueItemsGT1Mg(getNumRemainingTissueItemsGT1Mg() + 1);
1825 07 Feb 13 olle 835             }
1820 06 Feb 13 olle 836           }
1820 06 Feb 13 olle 837         }
1820 06 Feb 13 olle 838       }
1820 06 Feb 13 olle 839     }
1820 06 Feb 13 olle 840     else if (chartVariant.equals(minutesToRnaLaterChart))
1820 06 Feb 13 olle 841     {
2608 28 Aug 14 nicklas 842       for (Sample s: allSamples)
1820 06 Feb 13 olle 843       {
1840 13 Feb 13 olle 844         // Use QiaCube date of extract from lysate from sample
1820 06 Feb 13 olle 845         Date date = sampleIdQiaCubeDateHashMap.get(s.getId());              
1820 06 Feb 13 olle 846         if (date != null)
1820 06 Feb 13 olle 847         {
1820 06 Feb 13 olle 848           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 849               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 850           {
1820 06 Feb 13 olle 851             // Get current period
1820 06 Feb 13 olle 852             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 853             // Update period value hash map
1820 06 Feb 13 olle 854             Float value = null;
1820 06 Feb 13 olle 855             // Get minutes to RNAlater
1820 06 Feb 13 olle 856             Long minToRnaLater = sampleIdMinToRnaLaterHashMap.get(s.getId());
1837 13 Feb 13 olle 857             if (minToRnaLater != null)
1820 06 Feb 13 olle 858             {
1820 06 Feb 13 olle 859               value = (float) minToRnaLater;
1820 06 Feb 13 olle 860             }
1820 06 Feb 13 olle 861             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 862           }
1820 06 Feb 13 olle 863         }
1820 06 Feb 13 olle 864       }
1820 06 Feb 13 olle 865     }
1820 06 Feb 13 olle 866     else if (chartVariant.equals(histologyPieceQuantityChart))
1820 06 Feb 13 olle 867     {
1820 06 Feb 13 olle 868       for (Sample s: sampleHistologyList)
1820 06 Feb 13 olle 869       {
1840 13 Feb 13 olle 870         // Use QiaCube date of extract from lysate from parent sample for histology sample
1840 13 Feb 13 olle 871         Sample histologySampleParent = (Sample) s.getParent();
1840 13 Feb 13 olle 872         Date date = sampleIdQiaCubeDateHashMap.get(histologySampleParent.getId());              
1820 06 Feb 13 olle 873         if (date != null)
1820 06 Feb 13 olle 874         {
1820 06 Feb 13 olle 875           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 876               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 877           {
1820 06 Feb 13 olle 878             // Get current period
1820 06 Feb 13 olle 879             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 880             // Update period value hash map
1820 06 Feb 13 olle 881             Float value = null;
1820 06 Feb 13 olle 882             // Get value in mg (stored in microgram)
1820 06 Feb 13 olle 883             value = s.getOriginalQuantity()/1000.0f;
1820 06 Feb 13 olle 884             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 885           }
1820 06 Feb 13 olle 886         }
1820 06 Feb 13 olle 887       }
1820 06 Feb 13 olle 888     }
1820 06 Feb 13 olle 889     else if (chartVariant.equals(originalQuantityDnaChart))
1820 06 Feb 13 olle 890     {
1820 06 Feb 13 olle 891       for (Extract e: extractDnaList)
1820 06 Feb 13 olle 892       {
1840 13 Feb 13 olle 893         // Use QiaCube date of extract
1820 06 Feb 13 olle 894         Date date = extractIdQiaCubeDateHashMap.get(e.getId());                
1820 06 Feb 13 olle 895         if (date != null)
1820 06 Feb 13 olle 896         {
1820 06 Feb 13 olle 897           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 898               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 899           {
1820 06 Feb 13 olle 900             // Get current period
1820 06 Feb 13 olle 901             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 902             // Update period value hash map
1820 06 Feb 13 olle 903             Float value = null;
1820 06 Feb 13 olle 904             // Get DNA original quantity in microgram
1820 06 Feb 13 olle 905             value = e.getOriginalQuantity();
1820 06 Feb 13 olle 906             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 907           }
1820 06 Feb 13 olle 908         }        
1820 06 Feb 13 olle 909       }
1820 06 Feb 13 olle 910     }
1820 06 Feb 13 olle 911     else if (chartVariant.equals(dnaYieldChart))
1820 06 Feb 13 olle 912     {
1820 06 Feb 13 olle 913       for (Extract e: extractDnaList)
1820 06 Feb 13 olle 914       {
1840 13 Feb 13 olle 915         // Use QiaCube date of extract
1820 06 Feb 13 olle 916         Date date = extractIdQiaCubeDateHashMap.get(e.getId());                
1820 06 Feb 13 olle 917         if (date != null)
1820 06 Feb 13 olle 918         {
1820 06 Feb 13 olle 919           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 920               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 921           {
1820 06 Feb 13 olle 922             // Get current period
1820 06 Feb 13 olle 923             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 924             // Update period value hash map
1820 06 Feb 13 olle 925             Float value = null;
1820 06 Feb 13 olle 926             // Get DNA original quantity in microgram
1820 06 Feb 13 olle 927             Float dnaOriginalQuantity = e.getOriginalQuantity();
1820 06 Feb 13 olle 928             // Get tissue original quantity in mg
1820 06 Feb 13 olle 929             Integer sampleId = extractIdSampleIdHashMap.get(e.getId());
1820 06 Feb 13 olle 930             if (sampleId != null)
1820 06 Feb 13 olle 931             {
1820 06 Feb 13 olle 932               Float tissueQuantityUsed = getSampleIdTissueQuantityUsedHashMap().get(sampleId);
1820 06 Feb 13 olle 933               if (tissueQuantityUsed != null && tissueQuantityUsed > 0)
1820 06 Feb 13 olle 934               {
1820 06 Feb 13 olle 935                 tissueQuantityUsed /= 1000.0f;
1820 06 Feb 13 olle 936                 // Get DNA yield
1820 06 Feb 13 olle 937                 value = dnaOriginalQuantity/tissueQuantityUsed;
1820 06 Feb 13 olle 938               }
1820 06 Feb 13 olle 939             }
1820 06 Feb 13 olle 940             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 941           }
1820 06 Feb 13 olle 942         }        
1820 06 Feb 13 olle 943       }
1820 06 Feb 13 olle 944     }
1820 06 Feb 13 olle 945     else if (chartVariant.equals(dnaYieldCorrectedChart))
1820 06 Feb 13 olle 946     {
1820 06 Feb 13 olle 947       for (Extract e: extractDnaList)
1820 06 Feb 13 olle 948       {
1840 13 Feb 13 olle 949         // Use QiaCube date of extract
1820 06 Feb 13 olle 950         Date date = extractIdQiaCubeDateHashMap.get(e.getId());                
1820 06 Feb 13 olle 951         if (date != null)
1820 06 Feb 13 olle 952         {
1820 06 Feb 13 olle 953           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 954               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 955           {
1820 06 Feb 13 olle 956             // Get current period
1820 06 Feb 13 olle 957             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 958             // Update period value hash map
1820 06 Feb 13 olle 959             Float value = null;
1820 06 Feb 13 olle 960             // Get DNA original quantity in microgram
1820 06 Feb 13 olle 961             Float dnaOriginalQuantity = e.getOriginalQuantity();
1820 06 Feb 13 olle 962             // Get tissue original quantity in mg
1820 06 Feb 13 olle 963             Integer sampleId = extractIdSampleIdHashMap.get(e.getId());
1820 06 Feb 13 olle 964             if (sampleId != null)
1820 06 Feb 13 olle 965             {
1820 06 Feb 13 olle 966               Float tissueQuantityUsed = getSampleIdTissueQuantityUsedHashMap().get(sampleId);
1820 06 Feb 13 olle 967               if (tissueQuantityUsed != null && tissueQuantityUsed > 0)
1820 06 Feb 13 olle 968               {
1820 06 Feb 13 olle 969                 tissueQuantityUsed /= 1000.0f;
1820 06 Feb 13 olle 970                 // Correct for only processing half of the lysate volume
1820 06 Feb 13 olle 971                 tissueQuantityUsed /= 2.0f;
1820 06 Feb 13 olle 972                 // Get DNA yield
1820 06 Feb 13 olle 973                 value = dnaOriginalQuantity/tissueQuantityUsed;
1820 06 Feb 13 olle 974               }
1820 06 Feb 13 olle 975             }
1820 06 Feb 13 olle 976             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 977           }
1820 06 Feb 13 olle 978         }        
1820 06 Feb 13 olle 979       }
1820 06 Feb 13 olle 980     }
1820 06 Feb 13 olle 981     else if (chartVariant.equals(originalQuantityRnaChart))
1820 06 Feb 13 olle 982     {
1820 06 Feb 13 olle 983       for (Extract e: extractRnaList)
1820 06 Feb 13 olle 984       {
1840 13 Feb 13 olle 985         // Use QiaCube date of extract
1820 06 Feb 13 olle 986         Date date = extractIdQiaCubeDateHashMap.get(e.getId());                
1820 06 Feb 13 olle 987         if (date != null)
1820 06 Feb 13 olle 988         {
1820 06 Feb 13 olle 989           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 990               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 991           {
1820 06 Feb 13 olle 992             // Get current period
1820 06 Feb 13 olle 993             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 994             // Update period value hash map
1820 06 Feb 13 olle 995             Float value = null;
1820 06 Feb 13 olle 996             // Get RNA original quantity in microgram
1820 06 Feb 13 olle 997             value = e.getOriginalQuantity();
1820 06 Feb 13 olle 998             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 999           }
1820 06 Feb 13 olle 1000         }        
1820 06 Feb 13 olle 1001       }
1820 06 Feb 13 olle 1002     }
1820 06 Feb 13 olle 1003     else if (chartVariant.equals(rnaYieldChart))
1820 06 Feb 13 olle 1004     {
1820 06 Feb 13 olle 1005       for (Extract e: extractRnaList)
1820 06 Feb 13 olle 1006       {
1840 13 Feb 13 olle 1007         // Use QiaCube date of extract
1820 06 Feb 13 olle 1008         Date date = extractIdQiaCubeDateHashMap.get(e.getId());                
1820 06 Feb 13 olle 1009         if (date != null)
1820 06 Feb 13 olle 1010         {
1820 06 Feb 13 olle 1011           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 1012               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 1013           {
1820 06 Feb 13 olle 1014             // Get current period
1820 06 Feb 13 olle 1015             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 1016             // Update period value hash map
1820 06 Feb 13 olle 1017             Float value = null;
1820 06 Feb 13 olle 1018             // Get RNA original quantity in microgram
1820 06 Feb 13 olle 1019             Float rnaOriginalQuantity = e.getOriginalQuantity();
1820 06 Feb 13 olle 1020             // Get tissue original quantity in mg
1820 06 Feb 13 olle 1021             Integer sampleId = extractIdSampleIdHashMap.get(e.getId());
1820 06 Feb 13 olle 1022             if (sampleId != null)
1820 06 Feb 13 olle 1023             {
1820 06 Feb 13 olle 1024               Float tissueQuantityUsed = getSampleIdTissueQuantityUsedHashMap().get(sampleId);
1820 06 Feb 13 olle 1025               if (tissueQuantityUsed != null && tissueQuantityUsed > 0)
1820 06 Feb 13 olle 1026               {
1820 06 Feb 13 olle 1027                 tissueQuantityUsed /= 1000.0f;
1820 06 Feb 13 olle 1028                 // Get RNA yield
1820 06 Feb 13 olle 1029                 value = rnaOriginalQuantity/tissueQuantityUsed;
1820 06 Feb 13 olle 1030               }
1820 06 Feb 13 olle 1031             }
1820 06 Feb 13 olle 1032             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 1033           }
1820 06 Feb 13 olle 1034         }        
1820 06 Feb 13 olle 1035       }
1820 06 Feb 13 olle 1036     }
1820 06 Feb 13 olle 1037     else if (chartVariant.equals(rnaYieldCorrectedChart))
1820 06 Feb 13 olle 1038     {
1820 06 Feb 13 olle 1039       for (Extract e: extractRnaList)
1820 06 Feb 13 olle 1040       {
1840 13 Feb 13 olle 1041         // Use QiaCube date of extract
1820 06 Feb 13 olle 1042         Date date = extractIdQiaCubeDateHashMap.get(e.getId());                
1820 06 Feb 13 olle 1043         if (date != null)
1820 06 Feb 13 olle 1044         {
1820 06 Feb 13 olle 1045           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 1046               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 1047           {
1820 06 Feb 13 olle 1048             // Get current period
1820 06 Feb 13 olle 1049             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 1050             // Update period value hash map
1820 06 Feb 13 olle 1051             Float value = null;
1820 06 Feb 13 olle 1052             // Get RNA original quantity in microgram
1820 06 Feb 13 olle 1053             Float rnaOriginalQuantity = e.getOriginalQuantity();
1820 06 Feb 13 olle 1054             // Get tissue original quantity in mg
1820 06 Feb 13 olle 1055             Integer sampleId = extractIdSampleIdHashMap.get(e.getId());
1820 06 Feb 13 olle 1056             if (sampleId != null)
1820 06 Feb 13 olle 1057             {
1820 06 Feb 13 olle 1058               Float tissueQuantityUsed = getSampleIdTissueQuantityUsedHashMap().get(sampleId);
1820 06 Feb 13 olle 1059               if (tissueQuantityUsed != null && tissueQuantityUsed > 0)
1820 06 Feb 13 olle 1060               {
1820 06 Feb 13 olle 1061                 tissueQuantityUsed /= 1000.0f;
1820 06 Feb 13 olle 1062                 // Correct for only processing half of the lysate volume
1820 06 Feb 13 olle 1063                 tissueQuantityUsed /= 2.0f;
1820 06 Feb 13 olle 1064                 // Get RNA yield
1820 06 Feb 13 olle 1065                 value = rnaOriginalQuantity/tissueQuantityUsed;
1820 06 Feb 13 olle 1066               }
1820 06 Feb 13 olle 1067             }
1820 06 Feb 13 olle 1068             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 1069           }
1820 06 Feb 13 olle 1070         }        
1820 06 Feb 13 olle 1071       }
1820 06 Feb 13 olle 1072     }
1820 06 Feb 13 olle 1073     else if (chartVariant.equals(rnaQcChart))
1820 06 Feb 13 olle 1074     {
1820 06 Feb 13 olle 1075       for (Extract e: extractRnaQcList)
1820 06 Feb 13 olle 1076       {
1842 14 Feb 13 olle 1077         // Use QiaCube date of parent extract
1820 06 Feb 13 olle 1078         Date date = extractIdQiaCubeDateHashMap.get(e.getId());                
1820 06 Feb 13 olle 1079         if (date != null)
1820 06 Feb 13 olle 1080         {
1820 06 Feb 13 olle 1081           if ((date.after(startDate) || date.equals(startDate)) &&
1820 06 Feb 13 olle 1082               (date.before(endDate) || date.equals(endDate)))
1820 06 Feb 13 olle 1083           {
1820 06 Feb 13 olle 1084             // Get current period
1820 06 Feb 13 olle 1085             String currentPeriod = tableUtil.getCurrentPeriod(date, viewType);                        
1820 06 Feb 13 olle 1086             // Update period value hash map
1820 06 Feb 13 olle 1087             Float value = null;
1820 06 Feb 13 olle 1088             Float extractRqs = extractIdRqsHashMap.get(e.getId());
1842 14 Feb 13 olle 1089             if (extractRqs != null && extractRqs > 0.0f)
1820 06 Feb 13 olle 1090             {
1820 06 Feb 13 olle 1091               value = extractRqs;
1820 06 Feb 13 olle 1092             }
1820 06 Feb 13 olle 1093             else
1820 06 Feb 13 olle 1094             {
1820 06 Feb 13 olle 1095               Float extractRin = extractIdRinHashMap.get(e.getId());
1842 14 Feb 13 olle 1096               if (extractRin != null && extractRin > 0.0f)
1820 06 Feb 13 olle 1097               {
1820 06 Feb 13 olle 1098                 value = rqsRinFit(extractRin);
1820 06 Feb 13 olle 1099               }
1820 06 Feb 13 olle 1100             }
1820 06 Feb 13 olle 1101             updateStringFloatListHashMap(periodStringFloatListHashMap, currentPeriod, value);        
1820 06 Feb 13 olle 1102           }
1820 06 Feb 13 olle 1103         }
1820 06 Feb 13 olle 1104       }
1820 06 Feb 13 olle 1105     }
1820 06 Feb 13 olle 1106     return periodStringFloatListHashMap;        
1820 06 Feb 13 olle 1107   }
1820 06 Feb 13 olle 1108
1825 07 Feb 13 olle 1109   private JSONObject addExtraInfo(JSONObject plotJsonData, String chartVariant)
1825 07 Feb 13 olle 1110   {
1825 07 Feb 13 olle 1111     if (plotJsonData != null && chartVariant != null)
1825 07 Feb 13 olle 1112     {
1825 07 Feb 13 olle 1113       if (chartVariant.equals(remainingQuantityForScanBSpecimenChart))
1825 07 Feb 13 olle 1114       {
1825 07 Feb 13 olle 1115         String subTitleRight = (String) plotJsonData.get("subTitleRight");
1825 07 Feb 13 olle 1116         subTitleRight += "; > 1 mg, n = " + getNumRemainingTissueItemsGT1Mg();
1825 07 Feb 13 olle 1117         plotJsonData.put("subTitleRight", subTitleRight);
1825 07 Feb 13 olle 1118       }        
1825 07 Feb 13 olle 1119     }
1825 07 Feb 13 olle 1120     return plotJsonData;
1825 07 Feb 13 olle 1121   }
1825 07 Feb 13 olle 1122
1820 06 Feb 13 olle 1123   private Float rqsRinFit(Float rin)
1820 06 Feb 13 olle 1124   {
1820 06 Feb 13 olle 1125     Float rqsRin = null;
1820 06 Feb 13 olle 1126     if (rin != null)
1820 06 Feb 13 olle 1127     {
1820 06 Feb 13 olle 1128       rqsRin = rin*0.7698785f + 1.607572f;
1820 06 Feb 13 olle 1129     }
1820 06 Feb 13 olle 1130     return rqsRin;
1820 06 Feb 13 olle 1131   }
1820 06 Feb 13 olle 1132
1820 06 Feb 13 olle 1133   private HashMap<String, List<Float>> updateStringFloatListHashMap(HashMap<String, List<Float>> stringFloatListHashMap, String string, Float value)
1820 06 Feb 13 olle 1134   {
1820 06 Feb 13 olle 1135     if (stringFloatListHashMap == null)
1820 06 Feb 13 olle 1136     {
1820 06 Feb 13 olle 1137       stringFloatListHashMap = new HashMap<String, List<Float>>();
1820 06 Feb 13 olle 1138     }
1820 06 Feb 13 olle 1139     if (string != null && !string.equals("") && value != null)
1820 06 Feb 13 olle 1140     {
1820 06 Feb 13 olle 1141       List<Float> floatList = stringFloatListHashMap.get(string);
1820 06 Feb 13 olle 1142       if (floatList == null)
1820 06 Feb 13 olle 1143       {
1820 06 Feb 13 olle 1144         floatList = new ArrayList<Float>();
1820 06 Feb 13 olle 1145       }
1820 06 Feb 13 olle 1146       floatList.add(value);
1820 06 Feb 13 olle 1147       stringFloatListHashMap.put(string,  floatList);
1820 06 Feb 13 olle 1148     }
1820 06 Feb 13 olle 1149     return stringFloatListHashMap;
1820 06 Feb 13 olle 1150   }
1820 06 Feb 13 olle 1151
1820 06 Feb 13 olle 1152   /**
1820 06 Feb 13 olle 1153    *  Returns a single List<Float> with all values in all the
1820 06 Feb 13 olle 1154    *  lists in the HashMap<String, List<Float>>.
1820 06 Feb 13 olle 1155    *
1820 06 Feb 13 olle 1156    *  @param stringFloatListHashMap HashMap<String, List<Float>> The HashMap to use.
1820 06 Feb 13 olle 1157    *  @return List<Float> The list of float values in all the lists in the HashMap<String, List<Float>>.
1820 06 Feb 13 olle 1158    */
1820 06 Feb 13 olle 1159   private List<Float> singleFloatList(HashMap<String, List<Float>> stringFloatListHashMap)
1820 06 Feb 13 olle 1160   {
1820 06 Feb 13 olle 1161     List<Float> singleFloatList = new ArrayList<Float>();
1820 06 Feb 13 olle 1162     for (List<Float> floatList: stringFloatListHashMap.values())
1820 06 Feb 13 olle 1163     {
1820 06 Feb 13 olle 1164       for (Float value: floatList)
1820 06 Feb 13 olle 1165       {
1820 06 Feb 13 olle 1166         singleFloatList.add(value);
1820 06 Feb 13 olle 1167       }
1820 06 Feb 13 olle 1168     }
1820 06 Feb 13 olle 1169     return singleFloatList;
1820 06 Feb 13 olle 1170   }
1820 06 Feb 13 olle 1171
1820 06 Feb 13 olle 1172   private Float calculateMinValue(List<Float> floatList)
1820 06 Feb 13 olle 1173   {
1820 06 Feb 13 olle 1174     Float floatMin = Float.valueOf("1000000000.0");
1820 06 Feb 13 olle 1175     for (Float value: floatList)
1820 06 Feb 13 olle 1176     {
1820 06 Feb 13 olle 1177       if (value != null && value < floatMin)
1820 06 Feb 13 olle 1178       {
1820 06 Feb 13 olle 1179         floatMin = value;
1820 06 Feb 13 olle 1180       }
1820 06 Feb 13 olle 1181     }
1820 06 Feb 13 olle 1182     return floatMin;
1820 06 Feb 13 olle 1183   }
1820 06 Feb 13 olle 1184
1820 06 Feb 13 olle 1185   private Float calculateMaxValue(List<Float> floatList)
1820 06 Feb 13 olle 1186   {
1820 06 Feb 13 olle 1187     Float floatMax = Float.valueOf("-1000000000.0");
1820 06 Feb 13 olle 1188     for (Float value: floatList)
1820 06 Feb 13 olle 1189     {
1820 06 Feb 13 olle 1190       if (value != null && value > floatMax)
1820 06 Feb 13 olle 1191       {
1820 06 Feb 13 olle 1192         floatMax = value;
1820 06 Feb 13 olle 1193       }
1820 06 Feb 13 olle 1194     }
1820 06 Feb 13 olle 1195     return floatMax;
1820 06 Feb 13 olle 1196   }
1820 06 Feb 13 olle 1197
1820 06 Feb 13 olle 1198   private Float calculateMeanValue(List<Float> floatList)
1820 06 Feb 13 olle 1199   {
1820 06 Feb 13 olle 1200     Float mean = Float.valueOf("0.0");
1820 06 Feb 13 olle 1201     int n = 0;
1820 06 Feb 13 olle 1202     for (Float value: floatList)
1820 06 Feb 13 olle 1203     {
1820 06 Feb 13 olle 1204       if (value != null)
1820 06 Feb 13 olle 1205       {
1820 06 Feb 13 olle 1206         mean += value;
1820 06 Feb 13 olle 1207         n++;
1820 06 Feb 13 olle 1208       }
1820 06 Feb 13 olle 1209     }
1820 06 Feb 13 olle 1210     if (n > 0)
1820 06 Feb 13 olle 1211     {
1820 06 Feb 13 olle 1212       mean /= n;
1820 06 Feb 13 olle 1213     }
1820 06 Feb 13 olle 1214     return mean;
1820 06 Feb 13 olle 1215   }
1820 06 Feb 13 olle 1216
1820 06 Feb 13 olle 1217   private Float calculateSDev(List<Float> floatList)
1820 06 Feb 13 olle 1218   {
1820 06 Feb 13 olle 1219     Float var = Float.valueOf("0.0");
1820 06 Feb 13 olle 1220     Float mean = calculateMeanValue(floatList);
1820 06 Feb 13 olle 1221     int n = 0;
1820 06 Feb 13 olle 1222     Float dist = Float.valueOf("0.0");
1820 06 Feb 13 olle 1223     for (Float value: floatList)
1820 06 Feb 13 olle 1224     {
1820 06 Feb 13 olle 1225       if (value != null)
1820 06 Feb 13 olle 1226       {
1820 06 Feb 13 olle 1227         dist = (value - mean);
1820 06 Feb 13 olle 1228         var += dist*dist;
1820 06 Feb 13 olle 1229         n++;
1820 06 Feb 13 olle 1230       }
1820 06 Feb 13 olle 1231     }
1820 06 Feb 13 olle 1232     if (n > 1)
1820 06 Feb 13 olle 1233     {
1820 06 Feb 13 olle 1234       var /= (n - 1);
1820 06 Feb 13 olle 1235     }
1820 06 Feb 13 olle 1236     Float sDev = Double.valueOf(Math.sqrt(var)).floatValue();
1820 06 Feb 13 olle 1237     return sDev;
1820 06 Feb 13 olle 1238   }
1820 06 Feb 13 olle 1239
1820 06 Feb 13 olle 1240   private Float calculatePercentile(List<Float> sortedAscFloatList, float fraction)
1820 06 Feb 13 olle 1241   {
1820 06 Feb 13 olle 1242     Float percentileValue = null;
1820 06 Feb 13 olle 1243     if (sortedAscFloatList == null || sortedAscFloatList.size() < 1 || fraction <= 0.0 || fraction >= 1.0)
1820 06 Feb 13 olle 1244     {
1820 06 Feb 13 olle 1245       return null;
1820 06 Feb 13 olle 1246     }
1820 06 Feb 13 olle 1247     int len = sortedAscFloatList.size();
1820 06 Feb 13 olle 1248     // List index values goes from 0 to (len - 1)
1820 06 Feb 13 olle 1249     float indexVal = fraction*(len - 1);
1820 06 Feb 13 olle 1250     float floorVal = Double.valueOf(Math.floor(indexVal)).floatValue();
1820 06 Feb 13 olle 1251     float ceilVal = Double.valueOf(Math.ceil(indexVal)).floatValue();
1820 06 Feb 13 olle 1252     if (floorVal == ceilVal)
1820 06 Feb 13 olle 1253     {
1820 06 Feb 13 olle 1254       percentileValue = sortedAscFloatList.get((int) indexVal);
1820 06 Feb 13 olle 1255     }
1820 06 Feb 13 olle 1256     else
1820 06 Feb 13 olle 1257     {
1820 06 Feb 13 olle 1258       // Calculate percentile value as weighted value of two list values
1820 06 Feb 13 olle 1259       float d0 = sortedAscFloatList.get((int) floorVal) * (ceilVal - indexVal);
1820 06 Feb 13 olle 1260       float d1 = sortedAscFloatList.get((int) ceilVal)  * (indexVal - floorVal);
1820 06 Feb 13 olle 1261       percentileValue = d0 + d1;
1820 06 Feb 13 olle 1262     }
1820 06 Feb 13 olle 1263     return percentileValue;
1820 06 Feb 13 olle 1264   }
1820 06 Feb 13 olle 1265
1820 06 Feb 13 olle 1266   private Float calculateBoxPlotWhiskerValue(List<Float> sortedAscFloatList, Float pct25, Float pct75, float coef, String plotEnd)
1820 06 Feb 13 olle 1267   {
1820 06 Feb 13 olle 1268     Float whiskerValue = null;
1820 06 Feb 13 olle 1269     if (sortedAscFloatList == null || sortedAscFloatList.size() < 1 || pct25 == null || pct75 == null || coef <= 0.0 || plotEnd == null || !(plotEnd.equals("lower") || plotEnd.equals("upper")))
1820 06 Feb 13 olle 1270     {
1820 06 Feb 13 olle 1271       return null;
1820 06 Feb 13 olle 1272     }
1820 06 Feb 13 olle 1273     int len = sortedAscFloatList.size();
1820 06 Feb 13 olle 1274     // List index values goes from 0 to (len - 1)
1820 06 Feb 13 olle 1275     float ipr = pct75 - pct25;
1820 06 Feb 13 olle 1276     float limit = 0.0f;
1820 06 Feb 13 olle 1277     if (plotEnd.equals("lower"))
1820 06 Feb 13 olle 1278     {
1820 06 Feb 13 olle 1279       limit = pct25 - ipr*coef;
1820 06 Feb 13 olle 1280       float value = 1000000000.0f;
1820 06 Feb 13 olle 1281       for (int i=(len-1); i >= 0; i--)
1820 06 Feb 13 olle 1282       {
1820 06 Feb 13 olle 1283         value = sortedAscFloatList.get(i);
1820 06 Feb 13 olle 1284         if (value < limit)
1820 06 Feb 13 olle 1285         {
1820 06 Feb 13 olle 1286           break;
1820 06 Feb 13 olle 1287         }
1820 06 Feb 13 olle 1288         whiskerValue = value;
1820 06 Feb 13 olle 1289       }
1820 06 Feb 13 olle 1290     }
1820 06 Feb 13 olle 1291     else if (plotEnd.equals("upper"))
1820 06 Feb 13 olle 1292     {
1820 06 Feb 13 olle 1293       limit = pct75 + ipr*coef;
1820 06 Feb 13 olle 1294       float value = -1000000000.0f;
1820 06 Feb 13 olle 1295       for (int i=0; i < len; i++)
1820 06 Feb 13 olle 1296       {
1820 06 Feb 13 olle 1297         value = sortedAscFloatList.get(i);
1820 06 Feb 13 olle 1298         if (value > limit)
1820 06 Feb 13 olle 1299         {
1820 06 Feb 13 olle 1300           break;
1820 06 Feb 13 olle 1301         }
1820 06 Feb 13 olle 1302         whiskerValue = value;
1820 06 Feb 13 olle 1303       }
1820 06 Feb 13 olle 1304     }
1820 06 Feb 13 olle 1305     return whiskerValue;
1820 06 Feb 13 olle 1306   }
1820 06 Feb 13 olle 1307
1820 06 Feb 13 olle 1308   private HashMap<Integer, Float> updateSampleIdTissueQuantityUsedHashMap(Sample sample, Float usedQuantity)
1820 06 Feb 13 olle 1309   {
1820 06 Feb 13 olle 1310     if (sample != null && usedQuantity != null)
1820 06 Feb 13 olle 1311     {
1820 06 Feb 13 olle 1312       Float usedQuantityOld = getSampleIdTissueQuantityUsedHashMap().get(sample.getId());
1820 06 Feb 13 olle 1313       if (usedQuantityOld == null)
1820 06 Feb 13 olle 1314       {
1820 06 Feb 13 olle 1315         usedQuantityOld = 0.0f;
1820 06 Feb 13 olle 1316       }
1820 06 Feb 13 olle 1317       Float usedQuantityNew = usedQuantityOld + usedQuantity;
1820 06 Feb 13 olle 1318       getSampleIdTissueQuantityUsedHashMap().put(sample.getId(), usedQuantityNew);
1820 06 Feb 13 olle 1319     }
1820 06 Feb 13 olle 1320     return getSampleIdTissueQuantityUsedHashMap();
1820 06 Feb 13 olle 1321   }
1820 06 Feb 13 olle 1322
1820 06 Feb 13 olle 1323   /**
1820 06 Feb 13 olle 1324    *  Returns a chart header title given a chart variant string.
1820 06 Feb 13 olle 1325    *  If a plot is shown, this is normally the header title
1820 06 Feb 13 olle 1326    *  printed over the plot itself.
1820 06 Feb 13 olle 1327    *
1820 06 Feb 13 olle 1328    *  @param chartVariant String The chart variant to get a plot title for.
1820 06 Feb 13 olle 1329    *  @param viewType String The view type used for the period selection for the plot.
3571 30 Oct 15 nicklas 1330    *  @param site String The site used for the data selection for the plot.
1820 06 Feb 13 olle 1331    *  @return String A plot title for the given chart variant string.
1820 06 Feb 13 olle 1332    */
2608 28 Aug 14 nicklas 1333   private String fetchChartHeaderTitle(String chartVariant, String viewType, Site site)
1820 06 Feb 13 olle 1334   {
1820 06 Feb 13 olle 1335     // Get time period name for title
1820 06 Feb 13 olle 1336     String periodName = fetchTimePeriodName(viewType);
1820 06 Feb 13 olle 1337     // Get plot title
1820 06 Feb 13 olle 1338     String title = "New chart";
1820 06 Feb 13 olle 1339     if (chartVariant != null)
1820 06 Feb 13 olle 1340     {
1820 06 Feb 13 olle 1341       // String "\u00B5" is the micro character in unicode
1820 06 Feb 13 olle 1342       // String "\u223C" is the tilde character in unicode
1820 06 Feb 13 olle 1343       if (chartVariant.equals(originalQuantityTissueChart))
1820 06 Feb 13 olle 1344       {
1880 22 Feb 13 nicklas 1345         title = "Original quantity for SCANB specimens by " + periodName;
1820 06 Feb 13 olle 1346       }
1820 06 Feb 13 olle 1347       else if (chartVariant.equals(quantityTissueUsedChart))
1820 06 Feb 13 olle 1348       {
1820 06 Feb 13 olle 1349         title = "Quantity tissue used for SCANB specimens by " + periodName;
1820 06 Feb 13 olle 1350       }        
1820 06 Feb 13 olle 1351       else if (chartVariant.equals(histologyPieceQuantityChart))
1820 06 Feb 13 olle 1352       {
1820 06 Feb 13 olle 1353         title = "Histology piece quantity used for SCANB specimens by " + periodName;
1820 06 Feb 13 olle 1354       }        
1820 06 Feb 13 olle 1355       else if (chartVariant.equals(remainingQuantityForScanBSpecimenChart))
1820 06 Feb 13 olle 1356       {
1820 06 Feb 13 olle 1357         title = "Remaining tissue quantity for SCANB specimens by " + periodName;
1820 06 Feb 13 olle 1358       }        
1820 06 Feb 13 olle 1359       else if (chartVariant.equals(originalQuantityDnaChart))
1820 06 Feb 13 olle 1360       {
1880 22 Feb 13 nicklas 1361         title = "Total quantity DNA for SCANB extractions by " + periodName;
1820 06 Feb 13 olle 1362       }        
1820 06 Feb 13 olle 1363       else if (chartVariant.equals(originalQuantityRnaChart))
1820 06 Feb 13 olle 1364       {
1880 22 Feb 13 nicklas 1365         title = "Total quantity RNA for SCANB extractions by " + periodName;
1820 06 Feb 13 olle 1366       }        
1820 06 Feb 13 olle 1367       else if (chartVariant.equals(dnaYieldChart))
1820 06 Feb 13 olle 1368       {
1820 06 Feb 13 olle 1369         title = "DNA yield (\u00B5g/mg tissue) SCANB by " + periodName;
1820 06 Feb 13 olle 1370       }        
1820 06 Feb 13 olle 1371       else if (chartVariant.equals(rnaYieldChart))
1820 06 Feb 13 olle 1372       {
1820 06 Feb 13 olle 1373         title = "RNA yield (\u00B5g/mg tissue) SCANB by " + periodName;
1820 06 Feb 13 olle 1374       }        
1820 06 Feb 13 olle 1375       else if (chartVariant.equals(dnaYieldCorrectedChart))
1820 06 Feb 13 olle 1376       {
1820 06 Feb 13 olle 1377         title = "DNA yield corrected for lysate volume (\u00B5g/mg tissue) SCANB by " + periodName;
1820 06 Feb 13 olle 1378       }        
1820 06 Feb 13 olle 1379       else if (chartVariant.equals(rnaYieldCorrectedChart))
1820 06 Feb 13 olle 1380       {
1820 06 Feb 13 olle 1381         title = "RNA yield corrected for lysate volume (\u00B5g/mg tissue) SCANB by " + periodName;
1820 06 Feb 13 olle 1382       }        
1820 06 Feb 13 olle 1383       else if (chartVariant.equals(rnaQcChart))
1820 06 Feb 13 olle 1384       {
1820 06 Feb 13 olle 1385         title = "RNA QC SCANB by " + periodName;
1820 06 Feb 13 olle 1386         title = "RQS otherwise RQS\u223CRIN";
1820 06 Feb 13 olle 1387       }        
1820 06 Feb 13 olle 1388       else if (chartVariant.equals(minutesToRnaLaterChart))
1820 06 Feb 13 olle 1389       {
1820 06 Feb 13 olle 1390         title = "Minutes to RNAlater SCANB by " + periodName;
1820 06 Feb 13 olle 1391         title = "Min to RNAlater";
1855 18 Feb 13 olle 1392       }
2608 28 Aug 14 nicklas 1393       if (site != null)
1855 18 Feb 13 olle 1394       {
1855 18 Feb 13 olle 1395         // Add site name in parenthesis
2608 28 Aug 14 nicklas 1396         title += " (" + site.getName() + ")";
1855 18 Feb 13 olle 1397       }
1820 06 Feb 13 olle 1398     }
1820 06 Feb 13 olle 1399     return title;
1820 06 Feb 13 olle 1400   }
1820 06 Feb 13 olle 1401
1820 06 Feb 13 olle 1402   /**
1820 06 Feb 13 olle 1403    *  Returns the time period name for a view type string.
1820 06 Feb 13 olle 1404    *
1820 06 Feb 13 olle 1405    *  @param viewType String The view type used for time period selection.
1820 06 Feb 13 olle 1406    *  @return String The time period name.
1820 06 Feb 13 olle 1407    */
1820 06 Feb 13 olle 1408   private String fetchTimePeriodName(String viewType)
1820 06 Feb 13 olle 1409   {
1820 06 Feb 13 olle 1410     // Get time period name
1820 06 Feb 13 olle 1411     String periodName = "year";
2611 29 Aug 14 nicklas 1412     if (viewType.equals(ReportTableUtil.quarterView))
1820 06 Feb 13 olle 1413     {
1820 06 Feb 13 olle 1414       periodName = "quarter";
1820 06 Feb 13 olle 1415     }
2611 29 Aug 14 nicklas 1416     else if (viewType.equals(ReportTableUtil.monthView))
1820 06 Feb 13 olle 1417     {
1820 06 Feb 13 olle 1418       periodName = "month";
1820 06 Feb 13 olle 1419     }
2611 29 Aug 14 nicklas 1420     else if (viewType.equals(ReportTableUtil.weekView))
1820 06 Feb 13 olle 1421     {
1820 06 Feb 13 olle 1422       periodName = "week";
1820 06 Feb 13 olle 1423     }
1820 06 Feb 13 olle 1424     return periodName;
1820 06 Feb 13 olle 1425   }
1820 06 Feb 13 olle 1426
1820 06 Feb 13 olle 1427   /**
1820 06 Feb 13 olle 1428    *  Returns a chart title given a chart variant string.
1820 06 Feb 13 olle 1429    *
1820 06 Feb 13 olle 1430    *  @param chartVariant String The chart variant to get a title for.
1820 06 Feb 13 olle 1431    *  @return String A chart title for the given chart variant string.
1820 06 Feb 13 olle 1432    */
1820 06 Feb 13 olle 1433   private String fetchChartTitle(String chartVariant)
1820 06 Feb 13 olle 1434   {
1820 06 Feb 13 olle 1435     String title = "New chart";
1820 06 Feb 13 olle 1436     if (chartVariant != null)
1820 06 Feb 13 olle 1437     {
1820 06 Feb 13 olle 1438       // String "\u00B5" is the micro character in unicode
1820 06 Feb 13 olle 1439       // String "\u223C" is the tilde character in unicode
1820 06 Feb 13 olle 1440       if (chartVariant.equals(originalQuantityTissueChart))
1820 06 Feb 13 olle 1441       {
1820 06 Feb 13 olle 1442         title = "Original quantity tissue (mg)";
1820 06 Feb 13 olle 1443       }
1820 06 Feb 13 olle 1444       else if (chartVariant.equals(quantityTissueUsedChart))
1820 06 Feb 13 olle 1445       {
1820 06 Feb 13 olle 1446         title = "Quantity tissue used (mg)";
1820 06 Feb 13 olle 1447       }        
1820 06 Feb 13 olle 1448       else if (chartVariant.equals(histologyPieceQuantityChart))
1820 06 Feb 13 olle 1449       {
1820 06 Feb 13 olle 1450         title = "Histology piece quantity (mg)";
1820 06 Feb 13 olle 1451       }        
1820 06 Feb 13 olle 1452       else if (chartVariant.equals(remainingQuantityForScanBSpecimenChart))
1820 06 Feb 13 olle 1453       {
1820 06 Feb 13 olle 1454         title = "Remaining tissue (mg)";
1820 06 Feb 13 olle 1455       }        
1820 06 Feb 13 olle 1456       else if (chartVariant.equals(originalQuantityDnaChart))
1820 06 Feb 13 olle 1457       {
1820 06 Feb 13 olle 1458         title = "Original quantity DNA (\u00B5g)";
1820 06 Feb 13 olle 1459       }        
1820 06 Feb 13 olle 1460       else if (chartVariant.equals(originalQuantityRnaChart))
1820 06 Feb 13 olle 1461       {
1820 06 Feb 13 olle 1462         title = "Original quantity RNA (\u00B5g)";
1820 06 Feb 13 olle 1463       }        
1820 06 Feb 13 olle 1464       else if (chartVariant.equals(dnaYieldChart))
1820 06 Feb 13 olle 1465       {
1820 06 Feb 13 olle 1466         title = "DNA (\u00B5g)/ mg specimen tissue used";
1820 06 Feb 13 olle 1467       }        
1820 06 Feb 13 olle 1468       else if (chartVariant.equals(rnaYieldChart))
1820 06 Feb 13 olle 1469       {
1820 06 Feb 13 olle 1470         title = "RNA (\u00B5g)/ mg specimen tissue used";
1820 06 Feb 13 olle 1471       }        
1820 06 Feb 13 olle 1472       else if (chartVariant.equals(dnaYieldCorrectedChart))
1820 06 Feb 13 olle 1473       {
1820 06 Feb 13 olle 1474         title = "DNA (\u00B5g)/ mg specimen tissue used (corrected)";
1820 06 Feb 13 olle 1475       }        
1820 06 Feb 13 olle 1476       else if (chartVariant.equals(rnaYieldCorrectedChart))
1820 06 Feb 13 olle 1477       {
1820 06 Feb 13 olle 1478         title = "RNA (\u00B5g)/ mg specimen tissue used (corrected)";
1820 06 Feb 13 olle 1479       }        
1820 06 Feb 13 olle 1480       else if (chartVariant.equals(rnaQcChart))
1820 06 Feb 13 olle 1481       {
1820 06 Feb 13 olle 1482         title = "RQS otherwise RQS\u223CRIN";
1820 06 Feb 13 olle 1483       }        
1820 06 Feb 13 olle 1484       else if (chartVariant.equals(minutesToRnaLaterChart))
1820 06 Feb 13 olle 1485       {
1820 06 Feb 13 olle 1486         title = "Min to RNAlater";
1820 06 Feb 13 olle 1487       }        
1820 06 Feb 13 olle 1488     }
1820 06 Feb 13 olle 1489     return title;
1820 06 Feb 13 olle 1490   }
1820 06 Feb 13 olle 1491
1820 06 Feb 13 olle 1492   /**
1820 06 Feb 13 olle 1493    *  Returns a chart y-axis title given a chart variant string.
1820 06 Feb 13 olle 1494    *
1820 06 Feb 13 olle 1495    *  @param chartVariant String The chart variant to get a y-axis title for.
1820 06 Feb 13 olle 1496    *  @return String A chart y-axis title for the given chart variant string.
1820 06 Feb 13 olle 1497    */
1820 06 Feb 13 olle 1498   private String fetchChartYAxisTitle(String chartVariant)
1820 06 Feb 13 olle 1499   {
1820 06 Feb 13 olle 1500     String title = "New chart";
1820 06 Feb 13 olle 1501     if (chartVariant != null)
1820 06 Feb 13 olle 1502     {
1820 06 Feb 13 olle 1503       // String "\u00B5" is the micro character in unicode
1820 06 Feb 13 olle 1504       // String "\u223C" is the tilde character in unicode
1820 06 Feb 13 olle 1505       if (chartVariant.equals(originalQuantityTissueChart))
1820 06 Feb 13 olle 1506       {
1820 06 Feb 13 olle 1507         title = "mg";
1820 06 Feb 13 olle 1508       }
1820 06 Feb 13 olle 1509       else if (chartVariant.equals(quantityTissueUsedChart))
1820 06 Feb 13 olle 1510       {
1820 06 Feb 13 olle 1511         title = "mg";
1820 06 Feb 13 olle 1512       }        
1820 06 Feb 13 olle 1513       else if (chartVariant.equals(histologyPieceQuantityChart))
1820 06 Feb 13 olle 1514       {
1820 06 Feb 13 olle 1515         title = "mg";
1820 06 Feb 13 olle 1516       }        
1820 06 Feb 13 olle 1517       else if (chartVariant.equals(remainingQuantityForScanBSpecimenChart))
1820 06 Feb 13 olle 1518       {
1820 06 Feb 13 olle 1519         title = "mg";
1820 06 Feb 13 olle 1520       }        
1820 06 Feb 13 olle 1521       else if (chartVariant.equals(originalQuantityDnaChart))
1820 06 Feb 13 olle 1522       {
1820 06 Feb 13 olle 1523         title = "\u00B5g";
1820 06 Feb 13 olle 1524       }        
1820 06 Feb 13 olle 1525       else if (chartVariant.equals(originalQuantityRnaChart))
1820 06 Feb 13 olle 1526       {
1820 06 Feb 13 olle 1527         title = "\u00B5g";
1820 06 Feb 13 olle 1528       }        
1820 06 Feb 13 olle 1529       else if (chartVariant.equals(dnaYieldChart))
1820 06 Feb 13 olle 1530       {
1820 06 Feb 13 olle 1531         title = "\u00B5g/mg";
1820 06 Feb 13 olle 1532       }        
1820 06 Feb 13 olle 1533       else if (chartVariant.equals(rnaYieldChart))
1820 06 Feb 13 olle 1534       {
1820 06 Feb 13 olle 1535         title = "\u00B5g/mg";
1820 06 Feb 13 olle 1536       }        
1820 06 Feb 13 olle 1537       else if (chartVariant.equals(dnaYieldCorrectedChart))
1820 06 Feb 13 olle 1538       {
1820 06 Feb 13 olle 1539         title = "\u00B5g/mg";
1820 06 Feb 13 olle 1540       }        
1820 06 Feb 13 olle 1541       else if (chartVariant.equals(rnaYieldCorrectedChart))
1820 06 Feb 13 olle 1542       {
1820 06 Feb 13 olle 1543         title = "\u00B5g/mg";
1820 06 Feb 13 olle 1544       }        
1820 06 Feb 13 olle 1545       else if (chartVariant.equals(rnaQcChart))
1820 06 Feb 13 olle 1546       {
1820 06 Feb 13 olle 1547         title = "RQS otherwise RQS\u223CRIN";
1820 06 Feb 13 olle 1548       }        
1820 06 Feb 13 olle 1549       else if (chartVariant.equals(minutesToRnaLaterChart))
1820 06 Feb 13 olle 1550       {
1820 06 Feb 13 olle 1551         title = "Minutes";
1820 06 Feb 13 olle 1552       }        
1820 06 Feb 13 olle 1553     }
1820 06 Feb 13 olle 1554     return title;
1820 06 Feb 13 olle 1555   }
1820 06 Feb 13 olle 1556 }