extensions/net.sf.basedb.meludi/trunk/src/net/sf/basedb/meludi/counter/CounterService.java

Code
Comments
Other
Rev Date Author Line
3100 21 Jan 15 olle 1 package net.sf.basedb.meludi.counter;
3100 21 Jan 15 olle 2
3100 21 Jan 15 olle 3
3180 17 Mar 15 olle 4 import java.util.ArrayList;
5060 29 Oct 18 olle 5 import java.util.Date;
4127 26 Sep 16 olle 6 import java.util.HashMap;
3176 06 Mar 15 olle 7 import java.util.List;
4127 26 Sep 16 olle 8 import java.util.Set;
3100 21 Jan 15 olle 9 import java.util.TimerTask;
3100 21 Jan 15 olle 10
3100 21 Jan 15 olle 11 import net.sf.basedb.clients.web.extensions.service.Services;
3100 21 Jan 15 olle 12 import net.sf.basedb.core.Application;
3180 17 Mar 15 olle 13 import net.sf.basedb.core.BioPlate;
3100 21 Jan 15 olle 14 import net.sf.basedb.core.BioSource;
3100 21 Jan 15 olle 15 import net.sf.basedb.core.DbControl;
3100 21 Jan 15 olle 16 import net.sf.basedb.core.Extract;
3180 17 Mar 15 olle 17 import net.sf.basedb.core.HasAnnotationRestriction;
3644 03 Dec 15 olle 18 import net.sf.basedb.core.Include;
3432 29 Jun 15 olle 19 import net.sf.basedb.core.ItemList;
3100 21 Jan 15 olle 20 import net.sf.basedb.core.ItemQuery;
4127 26 Sep 16 olle 21 import net.sf.basedb.core.Project;
3100 21 Jan 15 olle 22 import net.sf.basedb.core.Sample;
3100 21 Jan 15 olle 23 import net.sf.basedb.core.SessionControl;
3180 17 Mar 15 olle 24 import net.sf.basedb.core.Type;
3180 17 Mar 15 olle 25 import net.sf.basedb.core.query.Expressions;
3100 21 Jan 15 olle 26 import net.sf.basedb.core.query.Hql;
3644 03 Dec 15 olle 27 import net.sf.basedb.core.query.Orders;
3100 21 Jan 15 olle 28 import net.sf.basedb.core.query.Restrictions;
3432 29 Jun 15 olle 29 import net.sf.basedb.core.snapshot.SnapshotManager;
3100 21 Jan 15 olle 30 import net.sf.basedb.meludi.Meludi;
3180 17 Mar 15 olle 31 import net.sf.basedb.meludi.dao.Annotationtype;
3180 17 Mar 15 olle 32 import net.sf.basedb.meludi.dao.BioplateType;
5158 30 Nov 18 olle 33 import net.sf.basedb.meludi.dao.Case;
5237 16 Jan 19 olle 34 import net.sf.basedb.meludi.dao.FfpeBlock;
3180 17 Mar 15 olle 35 import net.sf.basedb.meludi.dao.ReactionPlate;
3100 21 Jan 15 olle 36 import net.sf.basedb.meludi.dao.Subtype;
3100 21 Jan 15 olle 37 import net.sf.basedb.util.extensions.Extension;
3100 21 Jan 15 olle 38
3100 21 Jan 15 olle 39 import org.json.simple.JSONObject;
3100 21 Jan 15 olle 40 import org.slf4j.Logger;
3100 21 Jan 15 olle 41 import org.slf4j.LoggerFactory;
3100 21 Jan 15 olle 42
3100 21 Jan 15 olle 43 /**
3100 21 Jan 15 olle 44   Service for counting items at various steps in the lab
3100 21 Jan 15 olle 45   procedure. It will check the database at regular intervals and
3100 21 Jan 15 olle 46   count a lot of items.
3100 21 Jan 15 olle 47   
3100 21 Jan 15 olle 48   Note that checks are usually made in 60-minute intervals. 
3100 21 Jan 15 olle 49   Servlets and other code that is updating items should call
3100 21 Jan 15 olle 50   {@link #setForceCount()} to force a count more or less immediately.
3100 21 Jan 15 olle 51   
3100 21 Jan 15 olle 52   @author nicklas
3100 21 Jan 15 olle 53   @since 3.0
3100 21 Jan 15 olle 54 */
3100 21 Jan 15 olle 55 public class CounterService 
3100 21 Jan 15 olle 56 {
3100 21 Jan 15 olle 57
3100 21 Jan 15 olle 58   
3100 21 Jan 15 olle 59   private static final Logger logger = 
3100 21 Jan 15 olle 60     LoggerFactory.getLogger(CounterService.class);
3100 21 Jan 15 olle 61
3100 21 Jan 15 olle 62   // The singleton
3100 21 Jan 15 olle 63   private static CounterService instance = null;
3100 21 Jan 15 olle 64
3100 21 Jan 15 olle 65   // At most 60 minutes between counter updates (5 when debugging)
3100 21 Jan 15 olle 66   private static final long MAX_WAIT_INTERVAL = 
3100 21 Jan 15 olle 67     60000 * (logger.isDebugEnabled() ? 5 : 60);
3100 21 Jan 15 olle 68
3100 21 Jan 15 olle 69   
3100 21 Jan 15 olle 70   /**
3100 21 Jan 15 olle 71     Get the singleton instance of the service. If the service has
3100 21 Jan 15 olle 72     not been created yet it is created at this time.
3100 21 Jan 15 olle 73   */
3100 21 Jan 15 olle 74   public static final CounterService getInstance()
3100 21 Jan 15 olle 75   {
3100 21 Jan 15 olle 76     if (instance == null)
3100 21 Jan 15 olle 77     {
3100 21 Jan 15 olle 78       synchronized (CounterService.class)
3100 21 Jan 15 olle 79       {
3100 21 Jan 15 olle 80         if (instance == null)
3100 21 Jan 15 olle 81         {
3100 21 Jan 15 olle 82           CounterService tmp = new CounterService();
3100 21 Jan 15 olle 83           instance = tmp;
3100 21 Jan 15 olle 84         }
3100 21 Jan 15 olle 85       }
3100 21 Jan 15 olle 86     }
3100 21 Jan 15 olle 87     return instance;
3100 21 Jan 15 olle 88   }
3100 21 Jan 15 olle 89
3100 21 Jan 15 olle 90   private volatile boolean isRunning;
3100 21 Jan 15 olle 91   private SessionControl systemSc;
3100 21 Jan 15 olle 92   private Extension ext;
3100 21 Jan 15 olle 93   private TimerTask counterTimer;
3100 21 Jan 15 olle 94   
3100 21 Jan 15 olle 95   // Time when last count was made
3100 21 Jan 15 olle 96   private volatile long lastCount;
3100 21 Jan 15 olle 97   // If flag is set, we force a new count
3100 21 Jan 15 olle 98   private volatile boolean forceCount;
3100 21 Jan 15 olle 99   // Store the current counts
4127 26 Sep 16 olle 100   //private volatile JSONObject currentCounts;
4127 26 Sep 16 olle 101   // Store the current counts for all projects
4127 26 Sep 16 olle 102   private volatile JSONObject currentCountsAllProjects;
3100 21 Jan 15 olle 103   
3100 21 Jan 15 olle 104   private CounterService()
3100 21 Jan 15 olle 105   {}
3100 21 Jan 15 olle 106   
3100 21 Jan 15 olle 107   /**
3100 21 Jan 15 olle 108     Is the counter service running or not?
3100 21 Jan 15 olle 109   */
3100 21 Jan 15 olle 110   public boolean isRunning()
3100 21 Jan 15 olle 111   {
3100 21 Jan 15 olle 112     return isRunning;
3100 21 Jan 15 olle 113   }
3100 21 Jan 15 olle 114
3100 21 Jan 15 olle 115   /**
3100 21 Jan 15 olle 116     Start the service if it is not running.
3100 21 Jan 15 olle 117   */
3100 21 Jan 15 olle 118   public synchronized void start(SessionControl systemSc, Extension ext)
3100 21 Jan 15 olle 119   {
3100 21 Jan 15 olle 120     if (!isRunning)
3100 21 Jan 15 olle 121     {
3100 21 Jan 15 olle 122       logger.debug("Starting counter service");
3100 21 Jan 15 olle 123       this.systemSc = systemSc;
3100 21 Jan 15 olle 124       this.ext = ext;
4127 26 Sep 16 olle 125       //this.currentCounts = new JSONObject();
4127 26 Sep 16 olle 126       this.currentCountsAllProjects = new JSONObject();
3100 21 Jan 15 olle 127       
3100 21 Jan 15 olle 128       Meludi.getRootSessionControl(systemSc);
3100 21 Jan 15 olle 129       
3100 21 Jan 15 olle 130       counterTimer = Application.getScheduler().scheduleAtFixedRate(
3100 21 Jan 15 olle 131         new CounterTimerTask(), 1000, 1000, false);
3100 21 Jan 15 olle 132       
3100 21 Jan 15 olle 133       isRunning = true;
3100 21 Jan 15 olle 134       logger.debug("Counter service is now running");
3100 21 Jan 15 olle 135     }
3100 21 Jan 15 olle 136   }
3100 21 Jan 15 olle 137
3100 21 Jan 15 olle 138   /**
3100 21 Jan 15 olle 139     Stop the service if it is running.
3100 21 Jan 15 olle 140   */
3100 21 Jan 15 olle 141   public synchronized void stop()
3100 21 Jan 15 olle 142   {
3100 21 Jan 15 olle 143     if (isRunning)
3100 21 Jan 15 olle 144     {
3100 21 Jan 15 olle 145       logger.debug("Stopping counter service");
3100 21 Jan 15 olle 146       isRunning = false;
3100 21 Jan 15 olle 147
3100 21 Jan 15 olle 148       if (counterTimer != null)
3100 21 Jan 15 olle 149       {
3100 21 Jan 15 olle 150         counterTimer.cancel();
3100 21 Jan 15 olle 151         counterTimer = null;
3100 21 Jan 15 olle 152       }
3100 21 Jan 15 olle 153       systemSc = null;
3100 21 Jan 15 olle 154       ext = null;
3100 21 Jan 15 olle 155       lastCount = 0;
3100 21 Jan 15 olle 156       forceCount = false;
4127 26 Sep 16 olle 157       //currentCounts = null;
4127 26 Sep 16 olle 158       currentCountsAllProjects = null;
3100 21 Jan 15 olle 159       Meludi.closeRootSessionControl();
3100 21 Jan 15 olle 160       
3100 21 Jan 15 olle 161       logger.debug("Counter service has stopped");
3100 21 Jan 15 olle 162     }
3100 21 Jan 15 olle 163   }
3100 21 Jan 15 olle 164   
3100 21 Jan 15 olle 165   /**
3100 21 Jan 15 olle 166     Restart the service.
3100 21 Jan 15 olle 167   */
4145 03 Oct 16 olle 168   @SuppressWarnings("unchecked")
3100 21 Jan 15 olle 169   public synchronized void restart()
3100 21 Jan 15 olle 170   {
3100 21 Jan 15 olle 171     if (ext != null) Services.restart(ext);
3100 21 Jan 15 olle 172   }
3100 21 Jan 15 olle 173
3100 21 Jan 15 olle 174   /**
3100 21 Jan 15 olle 175     Set a flag forcing the service to perform a count at the next
3100 21 Jan 15 olle 176     timer event. This method should be called by servlets as soon
3100 21 Jan 15 olle 177     as they modify items.
3100 21 Jan 15 olle 178   */
3100 21 Jan 15 olle 179   public void setForceCount()
3100 21 Jan 15 olle 180   {
3100 21 Jan 15 olle 181     this.forceCount = true;
3100 21 Jan 15 olle 182   }
4127 26 Sep 16 olle 183
4127 26 Sep 16 olle 184 /*
3100 21 Jan 15 olle 185   public JSONObject getCurrentCounts()
3100 21 Jan 15 olle 186   {
3100 21 Jan 15 olle 187     return currentCounts;
3100 21 Jan 15 olle 188   }
4127 26 Sep 16 olle 189 */
3100 21 Jan 15 olle 190   
4127 26 Sep 16 olle 191   public JSONObject getCurrentProjectCounts(Integer projectId)
4127 26 Sep 16 olle 192   {
4127 26 Sep 16 olle 193     JSONObject curProjCounts = null;
4127 26 Sep 16 olle 194     if (projectId != null && projectId > 0)
4127 26 Sep 16 olle 195     {
4127 26 Sep 16 olle 196       curProjCounts = (JSONObject)currentCountsAllProjects.get(projectId);
4127 26 Sep 16 olle 197     }
4127 26 Sep 16 olle 198     return curProjCounts;
4127 26 Sep 16 olle 199   }
4127 26 Sep 16 olle 200   
3100 21 Jan 15 olle 201   /**
3100 21 Jan 15 olle 202     Perform a count. Note that this method may return without doing
3100 21 Jan 15 olle 203     anything depending on how long time it was since the last count and if
3100 21 Jan 15 olle 204     the {@link #setForceCount()} has been called or not.
3100 21 Jan 15 olle 205   */
4145 03 Oct 16 olle 206   @SuppressWarnings("unchecked")
3100 21 Jan 15 olle 207   void count()
3100 21 Jan 15 olle 208   {
3100 21 Jan 15 olle 209     long now = System.currentTimeMillis();
3100 21 Jan 15 olle 210     long timeSinceLastCheck = now - lastCount;
3100 21 Jan 15 olle 211
3100 21 Jan 15 olle 212     // If we have not waited long enough and there there is no recent request we don't have to check
3100 21 Jan 15 olle 213     if (timeSinceLastCheck < MAX_WAIT_INTERVAL && !forceCount)
3100 21 Jan 15 olle 214     {
3100 21 Jan 15 olle 215       logger.trace("No count since no recent change and not long enough wait time [" + (timeSinceLastCheck / 1000) + "]");
3100 21 Jan 15 olle 216       return;
3100 21 Jan 15 olle 217     }
3100 21 Jan 15 olle 218
3100 21 Jan 15 olle 219     forceCount = false;
3100 21 Jan 15 olle 220     lastCount = now;
3100 21 Jan 15 olle 221     logger.debug("Time for count [" + (timeSinceLastCheck / 1000) + "]");
3100 21 Jan 15 olle 222     int numItems = 0;
4127 26 Sep 16 olle 223
4127 26 Sep 16 olle 224 /*
3100 21 Jan 15 olle 225     SessionControl sc = Meludi.getRootSessionControl(systemSc);
3100 21 Jan 15 olle 226     DbControl dc = null;
3100 21 Jan 15 olle 227     try
3100 21 Jan 15 olle 228     {
3100 21 Jan 15 olle 229       dc = sc.newDbControl();
3100 21 Jan 15 olle 230       
3100 21 Jan 15 olle 231       JSONObject json = new JSONObject();
3100 21 Jan 15 olle 232       countPatients(dc, json);
3100 21 Jan 15 olle 233       countSpecimen(dc, json);
3100 21 Jan 15 olle 234       countExtracts(dc, json);
3180 17 Mar 15 olle 235       countExtractSourceItems(dc, json);
3103 22 Jan 15 olle 236       countCases(dc, json);
4915 16 Jul 18 olle 237       countFfpeBlocks(dc, json);
3180 17 Mar 15 olle 238       countBioPlates(dc, json);
3432 29 Jun 15 olle 239       countItemLists(dc, json);
3100 21 Jan 15 olle 240       
3100 21 Jan 15 olle 241       currentCounts = json;
3100 21 Jan 15 olle 242     }
3100 21 Jan 15 olle 243     finally
3100 21 Jan 15 olle 244     {
3100 21 Jan 15 olle 245       lastCount = System.currentTimeMillis();
3100 21 Jan 15 olle 246       if (dc != null) dc.close();
3100 21 Jan 15 olle 247       logger.debug("Count complete");
3100 21 Jan 15 olle 248     }
4127 26 Sep 16 olle 249 */
4127 26 Sep 16 olle 250     HashMap<Integer,SessionControl> projectIdScHM = Meludi.getRootSessionControlHM(systemSc);
4127 26 Sep 16 olle 251     if (projectIdScHM.size() > 0)
4127 26 Sep 16 olle 252     {
4127 26 Sep 16 olle 253       Set<Integer> keySet = projectIdScHM.keySet();
4127 26 Sep 16 olle 254       Integer[] keyArr = keySet.toArray(new Integer[keySet.size()]);
4127 26 Sep 16 olle 255       for (int i = 0; i < keySet.size(); i++)
4127 26 Sep 16 olle 256       {
4127 26 Sep 16 olle 257         int projectId = keyArr[i];
4127 26 Sep 16 olle 258         SessionControl sc = projectIdScHM.get(projectId);
4127 26 Sep 16 olle 259
4127 26 Sep 16 olle 260         DbControl dc = null;
4127 26 Sep 16 olle 261         try
4127 26 Sep 16 olle 262         {
4127 26 Sep 16 olle 263           dc = sc.newDbControl();
4127 26 Sep 16 olle 264           
4127 26 Sep 16 olle 265           JSONObject json = new JSONObject();
4127 26 Sep 16 olle 266           countPatients(dc, json);
4127 26 Sep 16 olle 267           countSpecimen(dc, json);
4127 26 Sep 16 olle 268           countExtracts(dc, json);
4127 26 Sep 16 olle 269           countExtractSourceItems(dc, json);
4127 26 Sep 16 olle 270           countCases(dc, json);
4915 16 Jul 18 olle 271           countFfpeBlocks(dc, json);
4127 26 Sep 16 olle 272           countBioPlates(dc, json);
4145 03 Oct 16 olle 273           countItemLists(dc, json, projectId);
4127 26 Sep 16 olle 274
4127 26 Sep 16 olle 275           currentCountsAllProjects.put(projectId, json);
4127 26 Sep 16 olle 276         }
4127 26 Sep 16 olle 277         finally
4127 26 Sep 16 olle 278         {
4127 26 Sep 16 olle 279           lastCount = System.currentTimeMillis();
4127 26 Sep 16 olle 280           if (dc != null) dc.close();
4127 26 Sep 16 olle 281         }
4127 26 Sep 16 olle 282       }
4127 26 Sep 16 olle 283       logger.debug("Count complete");
4127 26 Sep 16 olle 284     }
3100 21 Jan 15 olle 285   }
3100 21 Jan 15 olle 286
3100 21 Jan 15 olle 287
3100 21 Jan 15 olle 288   @SuppressWarnings("unchecked")
3100 21 Jan 15 olle 289   private void countPatients(DbControl dc, JSONObject json)
3100 21 Jan 15 olle 290   {
3100 21 Jan 15 olle 291     // All patients
3100 21 Jan 15 olle 292     ItemQuery<BioSource> query = BioSource.getQuery();
3100 21 Jan 15 olle 293     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3100 21 Jan 15 olle 294     Subtype.PATIENT.addFilter(dc, query);
3100 21 Jan 15 olle 295     query.setCacheResult(true);
3100 21 Jan 15 olle 296     json.put("patients-all", query.count(dc));
3100 21 Jan 15 olle 297   }
3100 21 Jan 15 olle 298   
3100 21 Jan 15 olle 299   @SuppressWarnings("unchecked")
3100 21 Jan 15 olle 300   private void countSpecimen(DbControl dc, JSONObject json)
3100 21 Jan 15 olle 301   {
3100 21 Jan 15 olle 302     // All specimen tubes
3100 21 Jan 15 olle 303     ItemQuery<Sample> query = Sample.getQuery();
3100 21 Jan 15 olle 304     Subtype.SPECIMEN.addFilter(dc, query);
3100 21 Jan 15 olle 305     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3100 21 Jan 15 olle 306     query.setCacheResult(true);
3100 21 Jan 15 olle 307     json.put("specimen-all", query.count(dc));
3176 06 Mar 15 olle 308
3176 06 Mar 15 olle 309     // All specimens without extracts
3176 06 Mar 15 olle 310     query = Sample.getQuery();
3176 06 Mar 15 olle 311     Subtype.SPECIMEN.addFilter(dc, query);
3176 06 Mar 15 olle 312     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3180 17 Mar 15 olle 313     query.restrict(Restrictions.eq(Hql.property("originalQuantity"), null));
3176 06 Mar 15 olle 314     // Restrict query to specimens with no child, if possible
3176 06 Mar 15 olle 315     List<Sample> specimenList = query.list(dc);
3176 06 Mar 15 olle 316     int numSpecimensWithoutExtract = 0;
3176 06 Mar 15 olle 317     for (Sample s: specimenList)
3176 06 Mar 15 olle 318     {
3176 06 Mar 15 olle 319       ItemQuery<Extract> specExtQuery = s.getExtracts();
3176 06 Mar 15 olle 320       // Must have a creation date and a parent (to get rid of stratagene)
3176 06 Mar 15 olle 321       // Filter on creation date==null and parent != null (eg. to get rid of 'Stratagene')
3176 06 Mar 15 olle 322       specExtQuery.join(Hql.innerJoin("creationEvent", "ce"));
3176 06 Mar 15 olle 323       specExtQuery.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3176 06 Mar 15 olle 324       specExtQuery.restrict(Restrictions.neq(Hql.property("parent"), null));
3176 06 Mar 15 olle 325       specExtQuery.setCacheResult(true);
3176 06 Mar 15 olle 326       if (specExtQuery.count(dc) == 0)
3176 06 Mar 15 olle 327       {
3176 06 Mar 15 olle 328         numSpecimensWithoutExtract++;
3176 06 Mar 15 olle 329       }
3176 06 Mar 15 olle 330     }
3176 06 Mar 15 olle 331     json.put("specimens-without-extract", numSpecimensWithoutExtract);
3180 17 Mar 15 olle 332   }
3100 21 Jan 15 olle 333   
3100 21 Jan 15 olle 334   @SuppressWarnings("unchecked")
3100 21 Jan 15 olle 335   private void countExtracts(DbControl dc, JSONObject json)
3100 21 Jan 15 olle 336   {
3100 21 Jan 15 olle 337     ItemQuery<Extract> query = Extract.getQuery();
3100 21 Jan 15 olle 338     
3100 21 Jan 15 olle 339     // All DNA that has been extracted
3100 21 Jan 15 olle 340     query = Extract.getQuery();
3100 21 Jan 15 olle 341     Subtype.DNA.addFilter(dc, query);
3100 21 Jan 15 olle 342     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3100 21 Jan 15 olle 343     // Must have a creation date and a parent (to get rid of stratagene)
3100 21 Jan 15 olle 344     // Filter on creation date==null and parent != null (eg. to get rid of 'Stratagene')
3100 21 Jan 15 olle 345     query.join(Hql.innerJoin("creationEvent", "ce"));
3100 21 Jan 15 olle 346     query.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3100 21 Jan 15 olle 347     query.restrict(Restrictions.neq(Hql.property("parent"), null));
3100 21 Jan 15 olle 348     query.setCacheResult(true);
3100 21 Jan 15 olle 349     json.put("dna-all-extracted", query.count(dc));
3100 21 Jan 15 olle 350     // ---
3100 21 Jan 15 olle 351     
3100 21 Jan 15 olle 352     // All RNA that has been extracted
3100 21 Jan 15 olle 353     query = Extract.getQuery();
3100 21 Jan 15 olle 354     Subtype.RNA.addFilter(dc, query);
3100 21 Jan 15 olle 355     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3100 21 Jan 15 olle 356     // Must have a creation date and a parent (to get rid of stratagene)
3100 21 Jan 15 olle 357     // Filter on creation date==null and parent != null (eg. to get rid of 'Stratagene')
3100 21 Jan 15 olle 358     query.join(Hql.innerJoin("creationEvent", "ce"));
3100 21 Jan 15 olle 359     query.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3100 21 Jan 15 olle 360     query.restrict(Restrictions.neq(Hql.property("parent"), null));
3100 21 Jan 15 olle 361     query.setCacheResult(true);
3100 21 Jan 15 olle 362     json.put("rna-all-extracted", query.count(dc));
3100 21 Jan 15 olle 363     // ---
3176 06 Mar 15 olle 364     
3176 06 Mar 15 olle 365     // All DNA without original quantity
3176 06 Mar 15 olle 366     query = Extract.getQuery();
3176 06 Mar 15 olle 367     Subtype.DNA.addFilter(dc, query);
3176 06 Mar 15 olle 368     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3176 06 Mar 15 olle 369     // Must have a creation date and a parent (to get rid of stratagene)
3176 06 Mar 15 olle 370     // Filter on creation date==null and parent != null (eg. to get rid of 'Stratagene')
3176 06 Mar 15 olle 371     // Filter on original_quantity==null
3176 06 Mar 15 olle 372     query.join(Hql.innerJoin("creationEvent", "ce"));
3176 06 Mar 15 olle 373     query.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3176 06 Mar 15 olle 374     query.restrict(Restrictions.neq(Hql.property("parent"), null));
3176 06 Mar 15 olle 375     query.restrict(Restrictions.eq(Hql.property("originalQuantity"), null));
3176 06 Mar 15 olle 376     query.setCacheResult(true);
3176 06 Mar 15 olle 377     json.put("dna-without-original-quantity", query.count(dc));
3176 06 Mar 15 olle 378     // ---
3176 06 Mar 15 olle 379     
3176 06 Mar 15 olle 380     // All RNA without original quantity
3176 06 Mar 15 olle 381     query = Extract.getQuery();
3176 06 Mar 15 olle 382     Subtype.RNA.addFilter(dc, query);
3176 06 Mar 15 olle 383     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3176 06 Mar 15 olle 384     // Must have a creation date and a parent (to get rid of stratagene)
3176 06 Mar 15 olle 385     // Filter on creation date==null and parent != null (eg. to get rid of 'Stratagene')
3176 06 Mar 15 olle 386     // Filter on original_quantity==null
3176 06 Mar 15 olle 387     query.join(Hql.innerJoin("creationEvent", "ce"));
3176 06 Mar 15 olle 388     query.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3176 06 Mar 15 olle 389     query.restrict(Restrictions.neq(Hql.property("parent"), null));
3176 06 Mar 15 olle 390     query.restrict(Restrictions.eq(Hql.property("originalQuantity"), null));
3176 06 Mar 15 olle 391     query.setCacheResult(true);
3176 06 Mar 15 olle 392     json.put("rna-without-original-quantity", query.count(dc));
3176 06 Mar 15 olle 393     // ---
3100 21 Jan 15 olle 394   }
3100 21 Jan 15 olle 395
3103 22 Jan 15 olle 396   @SuppressWarnings("unchecked")
3180 17 Mar 15 olle 397   private void countExtractSourceItems(DbControl dc, JSONObject json)
3180 17 Mar 15 olle 398   {
4246 21 Nov 16 olle 399     // All specimens with extracts, not already added to start list (= have original quantity `null`)
3180 17 Mar 15 olle 400     ItemQuery<Sample> specQuery = Sample.getQuery();
3180 17 Mar 15 olle 401     Subtype.SPECIMEN.addFilter(dc, specQuery);
3180 17 Mar 15 olle 402     specQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3180 17 Mar 15 olle 403     specQuery.restrict(Restrictions.eq(Hql.property("originalQuantity"), null));
3180 17 Mar 15 olle 404     // Restrict query to specimens with no child, if possible
3180 17 Mar 15 olle 405     List<Sample> specimenList = specQuery.list(dc);
4246 21 Nov 16 olle 406     int numUnprocessedSpecimensWithExtract = 0;
3180 17 Mar 15 olle 407     for (Sample s: specimenList)
3180 17 Mar 15 olle 408     {
3180 17 Mar 15 olle 409       ItemQuery<Extract> specExtQuery = s.getExtracts();
3180 17 Mar 15 olle 410       // Must have a creation date and a parent (to get rid of stratagene)
3180 17 Mar 15 olle 411       // Filter on creation date==null and parent != null (eg. to get rid of 'Stratagene')
3180 17 Mar 15 olle 412       specExtQuery.join(Hql.innerJoin("creationEvent", "ce"));
3180 17 Mar 15 olle 413       specExtQuery.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3180 17 Mar 15 olle 414       specExtQuery.restrict(Restrictions.neq(Hql.property("parent"), null));
3180 17 Mar 15 olle 415       specExtQuery.setCacheResult(true);
3180 17 Mar 15 olle 416       if (specExtQuery.count(dc) == 0)
3180 17 Mar 15 olle 417       {
4246 21 Nov 16 olle 418         if (s.countExtracts() > 0)
4246 21 Nov 16 olle 419         {
4246 21 Nov 16 olle 420           numUnprocessedSpecimensWithExtract++;
4246 21 Nov 16 olle 421         }
3180 17 Mar 15 olle 422       }
3180 17 Mar 15 olle 423     }
3180 17 Mar 15 olle 424
3180 17 Mar 15 olle 425     // All DNA without original quantity
3180 17 Mar 15 olle 426     ItemQuery<Extract> query = Extract.getQuery();
3180 17 Mar 15 olle 427     Subtype.DNA.addFilter(dc, query);
3180 17 Mar 15 olle 428     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3180 17 Mar 15 olle 429     // Must have a creation date and a parent (to get rid of stratagene)
3180 17 Mar 15 olle 430     // Filter on creation date==null and parent != null (eg. to get rid of 'Stratagene')
3180 17 Mar 15 olle 431     // Filter on original_quantity==null
3180 17 Mar 15 olle 432     query.join(Hql.innerJoin("creationEvent", "ce"));
3180 17 Mar 15 olle 433     query.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3180 17 Mar 15 olle 434     query.restrict(Restrictions.neq(Hql.property("parent"), null));
3180 17 Mar 15 olle 435     query.restrict(Restrictions.eq(Hql.property("originalQuantity"), null));
3180 17 Mar 15 olle 436     query.setCacheResult(true);
3180 17 Mar 15 olle 437     int numDnaWithoutOriginalQuantity = (int) query.count(dc);
3180 17 Mar 15 olle 438     // ---
3180 17 Mar 15 olle 439     
3180 17 Mar 15 olle 440     // All RNA without original quantity
3180 17 Mar 15 olle 441     query = Extract.getQuery();
3180 17 Mar 15 olle 442     Subtype.RNA.addFilter(dc, query);
3180 17 Mar 15 olle 443     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3180 17 Mar 15 olle 444     // Must have a creation date and a parent (to get rid of stratagene)
3180 17 Mar 15 olle 445     // Filter on creation date==null and parent != null (eg. to get rid of 'Stratagene')
3180 17 Mar 15 olle 446     // Filter on original_quantity==null
3180 17 Mar 15 olle 447     query.join(Hql.innerJoin("creationEvent", "ce"));
3180 17 Mar 15 olle 448     query.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3180 17 Mar 15 olle 449     query.restrict(Restrictions.neq(Hql.property("parent"), null));
3180 17 Mar 15 olle 450     query.restrict(Restrictions.eq(Hql.property("originalQuantity"), null));
3180 17 Mar 15 olle 451     query.setCacheResult(true);
3180 17 Mar 15 olle 452     int numRnaWithoutOriginalQuantity = (int) query.count(dc);
3180 17 Mar 15 olle 453     // ---
3180 17 Mar 15 olle 454
4246 21 Nov 16 olle 455     int numUnprocessedExtractSourceItems = numUnprocessedSpecimensWithExtract + numDnaWithoutOriginalQuantity + numRnaWithoutOriginalQuantity;
3180 17 Mar 15 olle 456     json.put("unprocessed-extract-source-items", numUnprocessedExtractSourceItems);
3180 17 Mar 15 olle 457   }
3180 17 Mar 15 olle 458
3180 17 Mar 15 olle 459   @SuppressWarnings("unchecked")
3103 22 Jan 15 olle 460   private void countCases(DbControl dc, JSONObject json)
3103 22 Jan 15 olle 461   {
3103 22 Jan 15 olle 462     // All cases
3103 22 Jan 15 olle 463     ItemQuery<Sample> query = Sample.getQuery();
3103 22 Jan 15 olle 464     Subtype.CASE.addFilter(dc, query);
3103 22 Jan 15 olle 465     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3103 22 Jan 15 olle 466     query.setCacheResult(true);
3103 22 Jan 15 olle 467     json.put("cases-all", query.count(dc));
3100 21 Jan 15 olle 468
3103 22 Jan 15 olle 469     // Cases without parent patient
3103 22 Jan 15 olle 470     query = Sample.getQuery();
3103 22 Jan 15 olle 471     Subtype.CASE.addFilter(dc, query);
3103 22 Jan 15 olle 472     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3103 22 Jan 15 olle 473     // Restrict query to cases with no parent
3103 22 Jan 15 olle 474     query.restrict(Restrictions.eq(Hql.property("parent"), null));
3103 22 Jan 15 olle 475     query.setCacheResult(true);
3103 22 Jan 15 olle 476     json.put("cases-without-patient", query.count(dc));
5158 30 Nov 18 olle 477     
5158 30 Nov 18 olle 478     // Cases with consent not used for FFPE block order forms
5158 30 Nov 18 olle 479     query = Sample.getQuery();
5158 30 Nov 18 olle 480     Subtype.CASE.addFilter(dc, query);
5158 30 Nov 18 olle 481     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
5158 30 Nov 18 olle 482     query.setCacheResult(true);
5158 30 Nov 18 olle 483     List<Sample> cases = query.list(dc);
5158 30 Nov 18 olle 484     // Case items unused for FFPE block order form
5158 30 Nov 18 olle 485     int numCasesUnusedForFfpeBlockOrderForm = 0;
5237 16 Jan 19 olle 486     int numCasesUsedForFfpeBlockOrderForm = 0;
5237 16 Jan 19 olle 487     int numCasesWithUnprocessedFfpeBlockOrders = 0;
5158 30 Nov 18 olle 488     for (int i = 0; i < cases.size(); i++)
5158 30 Nov 18 olle 489     {
5158 30 Nov 18 olle 490       Sample caseSample = (Sample) cases.get(i);
5158 30 Nov 18 olle 491 //System.out.println("CounterService::countCases(): i = " + i + " caseSample.getName() = " + caseSample.getName());
5158 30 Nov 18 olle 492       Case theCase = Case.findByName(dc, caseSample.getName());
5158 30 Nov 18 olle 493 //System.out.println("CounterService::countCases(): i = " + i + " theCase = " + theCase);
5158 30 Nov 18 olle 494       Date consentDate = null;
5158 30 Nov 18 olle 495       if (theCase != null)
5158 30 Nov 18 olle 496       {
5158 30 Nov 18 olle 497         //theCase.loadAnnotations(dc, "consent", Annotationtype.CONSENT, null);
5158 30 Nov 18 olle 498         theCase.loadAnnotations(dc, "consentDate", Annotationtype.CONSENT_DATE, Meludi.CONVERTER_DATE_TO_STRING);
5158 30 Nov 18 olle 499         consentDate = (Date) Annotationtype.CONSENT_DATE.getAnnotationValue(dc, theCase.getSample());        
5158 30 Nov 18 olle 500       }
5158 30 Nov 18 olle 501 //System.out.println("CounterService::countCases(): i = " + i + " consentDate = " + consentDate);
5158 30 Nov 18 olle 502       if (consentDate != null)
5158 30 Nov 18 olle 503       {
5237 16 Jan 19 olle 504         theCase.loadAnnotations(dc, "referralId", Annotationtype.REFERRAL_ID, null);
5237 16 Jan 19 olle 505         String referralId = (String) Annotationtype.REFERRAL_ID.getAnnotationValue(dc, caseSample);
5243 17 Jan 19 olle 506         Date ffpeBlockOrderDate = (Date) Annotationtype.FFPE_BLOCK_ORDER_DATE.getAnnotationValue(dc, caseSample);
5243 17 Jan 19 olle 507 System.out.println("CounterService::countCases(): i = " + i + " case = " + theCase.getName() + " ffpeBlockOrderDate = " + ffpeBlockOrderDate);
5243 17 Jan 19 olle 508         if (ffpeBlockOrderDate == null)
5158 30 Nov 18 olle 509         {
5158 30 Nov 18 olle 510           if (referralId != null && !referralId.equals(""))
5158 30 Nov 18 olle 511           {
5158 30 Nov 18 olle 512             numCasesUnusedForFfpeBlockOrderForm++;
5158 30 Nov 18 olle 513           }
5158 30 Nov 18 olle 514         }
5237 16 Jan 19 olle 515         else
5237 16 Jan 19 olle 516         {
5237 16 Jan 19 olle 517           // Case is used for FFPE block order form
5237 16 Jan 19 olle 518           boolean ffpeBlockExistsForCase = false;
5237 16 Jan 19 olle 519           if (referralId != null && !referralId.equals(""))
5237 16 Jan 19 olle 520           {
5237 16 Jan 19 olle 521             numCasesUsedForFfpeBlockOrderForm++;
5237 16 Jan 19 olle 522             // Check if FFPE block item exists for case
5237 16 Jan 19 olle 523             String caseName = theCase.getName();
5237 16 Jan 19 olle 524             query = Sample.getQuery();
5237 16 Jan 19 olle 525             Subtype.FFPE_BLOCK.addFilter(dc, query);
5237 16 Jan 19 olle 526             query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
5237 16 Jan 19 olle 527             query.setCacheResult(true);
5237 16 Jan 19 olle 528             List<Sample> ffpeBlocks = query.list(dc);
5237 16 Jan 19 olle 529             for (int j = 0; j < ffpeBlocks.size(); j++)
5237 16 Jan 19 olle 530             {
5237 16 Jan 19 olle 531               Sample ffpeBlockSample = (Sample) ffpeBlocks.get(j);
5237 16 Jan 19 olle 532               FfpeBlock ffpeBlock = FfpeBlock.getByName(dc, ffpeBlockSample.getName());
5237 16 Jan 19 olle 533               ffpeBlock.loadAnnotations(dc, "caseId", Annotationtype.CASE_ID, null);
5237 16 Jan 19 olle 534               String caseId = (String) Annotationtype.CASE_ID.getAnnotationValue(dc, ffpeBlockSample);
5237 16 Jan 19 olle 535               if (caseId != null && caseId.equals(caseName))
5237 16 Jan 19 olle 536               {
5237 16 Jan 19 olle 537                 ffpeBlockExistsForCase = true;
5237 16 Jan 19 olle 538                 break;
5237 16 Jan 19 olle 539               }
5237 16 Jan 19 olle 540             }
5237 16 Jan 19 olle 541             if (!ffpeBlockExistsForCase)
5237 16 Jan 19 olle 542             {
5237 16 Jan 19 olle 543               numCasesWithUnprocessedFfpeBlockOrders++;
5237 16 Jan 19 olle 544             }
5237 16 Jan 19 olle 545           }
5237 16 Jan 19 olle 546         }
5158 30 Nov 18 olle 547       }
5158 30 Nov 18 olle 548     }
5158 30 Nov 18 olle 549 //System.out.println("CounterService::countCases(): numCasesUnusedForFfpeBlockOrderForm = " + numCasesUnusedForFfpeBlockOrderForm);
5158 30 Nov 18 olle 550     json.put("cases-unused-for-ffpe-block-order-form", numCasesUnusedForFfpeBlockOrderForm);    
5237 16 Jan 19 olle 551     json.put("cases-used-for-ffpe-block-order-form", numCasesUsedForFfpeBlockOrderForm);    
5237 16 Jan 19 olle 552     json.put("cases-with-unprocessed-ffpe-block-orders", numCasesWithUnprocessedFfpeBlockOrders);    
3103 22 Jan 15 olle 553   }
3103 22 Jan 15 olle 554   
3180 17 Mar 15 olle 555   @SuppressWarnings("unchecked")
4915 16 Jul 18 olle 556   private void countFfpeBlocks(DbControl dc, JSONObject json)
4915 16 Jul 18 olle 557   {
4915 16 Jul 18 olle 558     // All FFPE block items
4915 16 Jul 18 olle 559     ItemQuery<Sample> query = Sample.getQuery();
4915 16 Jul 18 olle 560     Subtype.FFPE_BLOCK.addFilter(dc, query);
4915 16 Jul 18 olle 561     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
4915 16 Jul 18 olle 562     query.setCacheResult(true);
4915 16 Jul 18 olle 563     json.put("ffpeblocks-all", query.count(dc));
5052 25 Oct 18 olle 564     
5060 29 Oct 18 olle 565     // FFPE block items used and unused for sections 
5052 25 Oct 18 olle 566     List<Sample> ffpeBlocks = query.list(dc);
5060 29 Oct 18 olle 567     int numUnreturnedFfpeBlocks = 0;
5060 29 Oct 18 olle 568     int numReturnedFfpeBlocks = 0;
5061 30 Oct 18 olle 569     int numFfpeBlocksUnusedForSectionOrderForm = 0;
5061 30 Oct 18 olle 570     int numFfpeBlocksUnusedForSection = 0;
5060 29 Oct 18 olle 571     int numUsedFfpeBlocks = 0;
5052 25 Oct 18 olle 572     for (int i = 0; i < ffpeBlocks.size(); i++)
5052 25 Oct 18 olle 573     {
5052 25 Oct 18 olle 574       Sample ffpeBlock = (Sample) ffpeBlocks.get(i);
5060 29 Oct 18 olle 575       Date returnedDate = (Date) Annotationtype.RETURNED_DATE.getAnnotationValue(dc, ffpeBlock);
5060 29 Oct 18 olle 576       if (returnedDate == null)
5052 25 Oct 18 olle 577       {
5060 29 Oct 18 olle 578         numUnreturnedFfpeBlocks++;
5061 30 Oct 18 olle 579         Boolean isUsedForFfpeSectionOrderForm = (Boolean) Annotationtype.USED_FOR_FFPE_SECTION_ORDER_FORM.getAnnotationValue(dc, ffpeBlock);
5061 30 Oct 18 olle 580         Boolean isUsedForFfpeSection = (Boolean) Annotationtype.USED_FOR_FFPE_SECTION.getAnnotationValue(dc, ffpeBlock);
5061 30 Oct 18 olle 581         if (isUsedForFfpeSectionOrderForm == null || !isUsedForFfpeSectionOrderForm)
5060 29 Oct 18 olle 582         {
5061 30 Oct 18 olle 583           numFfpeBlocksUnusedForSectionOrderForm++;
5060 29 Oct 18 olle 584         }
5824 04 Feb 20 olle 585         else if (isUsedForFfpeSection == null || !isUsedForFfpeSection)
5235 16 Jan 19 olle 586         {
5235 16 Jan 19 olle 587           numFfpeBlocksUnusedForSection++;
5235 16 Jan 19 olle 588         }
5060 29 Oct 18 olle 589         else
5060 29 Oct 18 olle 590         {
5235 16 Jan 19 olle 591           numUsedFfpeBlocks++;
5060 29 Oct 18 olle 592         }
5052 25 Oct 18 olle 593       }
5060 29 Oct 18 olle 594       else
5060 29 Oct 18 olle 595       {
5060 29 Oct 18 olle 596         numReturnedFfpeBlocks++;
5060 29 Oct 18 olle 597       }
5052 25 Oct 18 olle 598     }
5060 29 Oct 18 olle 599     json.put("ffpeblocks-unreturned", numUnreturnedFfpeBlocks);
5060 29 Oct 18 olle 600     json.put("ffpeblocks-returned", numReturnedFfpeBlocks);
5061 30 Oct 18 olle 601     json.put("ffpeblocks-unused-for-section-order-form", numFfpeBlocksUnusedForSectionOrderForm);
5061 30 Oct 18 olle 602     json.put("ffpeblocks-unused-for-section", numFfpeBlocksUnusedForSection);
5060 29 Oct 18 olle 603     json.put("ffpeblocks-used", numUsedFfpeBlocks);
4915 16 Jul 18 olle 604   }
4915 16 Jul 18 olle 605   
4915 16 Jul 18 olle 606   @SuppressWarnings("unchecked")
3180 17 Mar 15 olle 607   private void countBioPlates(DbControl dc, JSONObject json)
3180 17 Mar 15 olle 608   {
3180 17 Mar 15 olle 609     ItemQuery<BioPlate> query = BioPlate.getQuery();
3206 20 Mar 15 olle 610
3206 20 Mar 15 olle 611     // All DNA plates
3206 20 Mar 15 olle 612     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3206 20 Mar 15 olle 613     query.join(Hql.innerJoin("bioPlateType", "bpt"));
3206 20 Mar 15 olle 614     BioplateType.DNA.addFilter(dc, query, false);
3206 20 Mar 15 olle 615     //query.restrict(Restrictions.eq(Hql.property("destroyed"), Expressions.parameter("destroyed", false, Type.BOOLEAN)));
3206 20 Mar 15 olle 616     query.setCacheResult(true);
3206 20 Mar 15 olle 617     json.put("dna-plates", query.count(dc));
3206 20 Mar 15 olle 618
3180 17 Mar 15 olle 619     // All active DNA plates with event date not set
3206 20 Mar 15 olle 620     query = BioPlate.getQuery();
3180 17 Mar 15 olle 621     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3180 17 Mar 15 olle 622     query.join(Hql.innerJoin("bioPlateType", "bpt"));
3180 17 Mar 15 olle 623     BioplateType.DNA.addFilter(dc, query, false);
3180 17 Mar 15 olle 624     int numFreeWells = 0;
3180 17 Mar 15 olle 625     query.restrict(Restrictions.eq(Hql.property("eventDate"), null));
3180 17 Mar 15 olle 626     query.restrict(Restrictions.eq(Hql.property("destroyed"), Expressions.parameter("destroyed", false, Type.BOOLEAN)));
3180 17 Mar 15 olle 627     query.restrict(Restrictions.gteq(Hql.property("freeWells"), Expressions.integer(numFreeWells)));
3180 17 Mar 15 olle 628     query.setCacheResult(true);
3180 17 Mar 15 olle 629     json.put("dna-plates-without-eventdate", query.count(dc));
3180 17 Mar 15 olle 630   }
3103 22 Jan 15 olle 631
3432 29 Jun 15 olle 632   @SuppressWarnings("unchecked")
4145 03 Oct 16 olle 633   private void countItemLists(DbControl dc, JSONObject json, int projectId)
3432 29 Jun 15 olle 634   {
3432 29 Jun 15 olle 635     ItemQuery<ItemList> query = ItemList.getQuery();
3180 17 Mar 15 olle 636
3432 29 Jun 15 olle 637     // All start item lists
3432 29 Jun 15 olle 638     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
4145 03 Oct 16 olle 639     query.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", Meludi.fetchStartListItemPrefix(projectId) + "%", Type.STRING)));
3432 29 Jun 15 olle 640     //query.restrict(Restrictions.eq(Hql.property("destroyed"), Expressions.parameter("destroyed", false, Type.BOOLEAN)));
3432 29 Jun 15 olle 641     query.setCacheResult(true);
3432 29 Jun 15 olle 642     json.put("start-lists", query.count(dc));
3432 29 Jun 15 olle 643
3432 29 Jun 15 olle 644     // Use stored annotation snapshots for performance reasons
3432 29 Jun 15 olle 645     SnapshotManager manager = new SnapshotManager();        
3432 29 Jun 15 olle 646     // All active start item lists with annotation Annotationtype.SAMPLE_PREP_LIST_IS_PROCESSED not set
3432 29 Jun 15 olle 647     List<ItemList> startItemLists = query.list(dc);
3432 29 Jun 15 olle 648     int numStartListNotProcessed = 0;
3444 22 Jul 15 olle 649     int numStartListProcessed = 0;
3644 03 Dec 15 olle 650     int numStartListProcessedOneItemNotOnLibPlate = 0;
3432 29 Jun 15 olle 651     for (ItemList itemList: startItemLists)
3432 29 Jun 15 olle 652     {
3432 29 Jun 15 olle 653       Boolean isProcessed = (Boolean) Annotationtype.SAMPLE_PREP_LIST_IS_PROCESSED.getAnnotationValue(dc, itemList);
3432 29 Jun 15 olle 654       if (isProcessed == null || !isProcessed)
3432 29 Jun 15 olle 655       {
3432 29 Jun 15 olle 656         numStartListNotProcessed++;
3432 29 Jun 15 olle 657       }
3444 22 Jul 15 olle 658       else
3444 22 Jul 15 olle 659       {
3444 22 Jul 15 olle 660         numStartListProcessed++;
3644 03 Dec 15 olle 661
3644 03 Dec 15 olle 662         // Check if all DNA extract items in list have FPA child extracts
3644 03 Dec 15 olle 663         boolean oneItemWithoutFpaChild = false;
3644 03 Dec 15 olle 664         // Construct a query to get all member extract items in the item list, sorted alphabetically after name
3644 03 Dec 15 olle 665         ItemQuery<Extract> extractQuery = (ItemQuery<Extract>)itemList.getMembers();
3644 03 Dec 15 olle 666         extractQuery.include(Include.ALL);
3644 03 Dec 15 olle 667         extractQuery.order(Orders.asc(Hql.property("name")));
3644 03 Dec 15 olle 668         List<Extract> extractList = extractQuery.list(dc);
3644 03 Dec 15 olle 669         for (int i = 0; i < extractList.size() && !oneItemWithoutFpaChild; i++)
3644 03 Dec 15 olle 670         {
3644 03 Dec 15 olle 671           Extract e = (Extract) extractList.get(i);
3644 03 Dec 15 olle 672           if (e != null)
3644 03 Dec 15 olle 673           {
3644 03 Dec 15 olle 674             if (Meludi.itemIsDna(e.getName()))
3644 03 Dec 15 olle 675             {
3719 22 Jan 16 olle 676               // Ignore DNA extracts marked for qPCR processing
3719 22 Jan 16 olle 677               Boolean markedForQPcr = (Boolean) Annotationtype.QPCR_BRANCH.getAnnotationValue(dc, e);
3719 22 Jan 16 olle 678               if (markedForQPcr == null || !markedForQPcr)
3644 03 Dec 15 olle 679               {
3719 22 Jan 16 olle 680                 ItemQuery<Extract> childQuery = e.getChildExtracts();
3719 22 Jan 16 olle 681                 List<Extract> childExtracts = childQuery.list(dc);
3719 22 Jan 16 olle 682                 if (childExtracts == null)
3644 03 Dec 15 olle 683                 {
3719 22 Jan 16 olle 684                   oneItemWithoutFpaChild = true;
3719 22 Jan 16 olle 685                 }
3719 22 Jan 16 olle 686                 else
3719 22 Jan 16 olle 687                 {
3719 22 Jan 16 olle 688                   // Search for FPA aliquot child extracts
3719 22 Jan 16 olle 689                   boolean fpaAliquotFound = false;
3719 22 Jan 16 olle 690                   for (int j = 0; j < childExtracts.size() && !fpaAliquotFound; j++)
3644 03 Dec 15 olle 691                   {
3719 22 Jan 16 olle 692                     Extract childExtract = (Extract) childExtracts.get(j);
3719 22 Jan 16 olle 693                     String childName = childExtract.getName();
3719 22 Jan 16 olle 694                     if (childName.endsWith(".fpa"))
3719 22 Jan 16 olle 695                     {
3719 22 Jan 16 olle 696                       fpaAliquotFound = true;
3719 22 Jan 16 olle 697                     }
3644 03 Dec 15 olle 698                   }
3719 22 Jan 16 olle 699                   if (!fpaAliquotFound)
3719 22 Jan 16 olle 700                   {
3719 22 Jan 16 olle 701                     oneItemWithoutFpaChild = true;
3719 22 Jan 16 olle 702                   }
3644 03 Dec 15 olle 703                 }
3644 03 Dec 15 olle 704               }
3644 03 Dec 15 olle 705             }
3644 03 Dec 15 olle 706           }
3644 03 Dec 15 olle 707         }
3644 03 Dec 15 olle 708         if (oneItemWithoutFpaChild)
3644 03 Dec 15 olle 709         {
3644 03 Dec 15 olle 710           numStartListProcessedOneItemNotOnLibPlate++;
3644 03 Dec 15 olle 711         }
3444 22 Jul 15 olle 712       }
3432 29 Jun 15 olle 713     }
3432 29 Jun 15 olle 714     json.put("start-lists-not-processed", numStartListNotProcessed);
3444 22 Jul 15 olle 715     json.put("start-lists-processed", numStartListProcessed);
3644 03 Dec 15 olle 716     json.put("start-lists-processed-an-item-not-on-lib-plate", numStartListProcessedOneItemNotOnLibPlate);
3432 29 Jun 15 olle 717   }
3432 29 Jun 15 olle 718
3432 29 Jun 15 olle 719
3100 21 Jan 15 olle 720   /**
3100 21 Jan 15 olle 721     Timer for auto-confirmation
3100 21 Jan 15 olle 722   */
3100 21 Jan 15 olle 723   static class CounterTimerTask
3100 21 Jan 15 olle 724     extends TimerTask
3100 21 Jan 15 olle 725   {
3100 21 Jan 15 olle 726     
3100 21 Jan 15 olle 727     public CounterTimerTask() 
3100 21 Jan 15 olle 728     {}
3100 21 Jan 15 olle 729     
3100 21 Jan 15 olle 730     @Override
3100 21 Jan 15 olle 731     public void run()
3100 21 Jan 15 olle 732     {
3100 21 Jan 15 olle 733       try
3100 21 Jan 15 olle 734       {
3100 21 Jan 15 olle 735         getInstance().count();
3100 21 Jan 15 olle 736       }
3100 21 Jan 15 olle 737       catch (Exception ex)
3100 21 Jan 15 olle 738       {
3100 21 Jan 15 olle 739         logger.error("Exception when performing count", ex);
3100 21 Jan 15 olle 740       }
3100 21 Jan 15 olle 741     }
3100 21 Jan 15 olle 742
3100 21 Jan 15 olle 743   }
3100 21 Jan 15 olle 744   
3100 21 Jan 15 olle 745 }