@Override @SuppressWarnings(value = "unchecked") public RunImportData constructRunImportData() { // Instanciate the DOM document DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); docFactory.setIgnoringComments(true); docFactory.setIgnoringElementContentWhitespace(true); docFactory.setValidating(false); DocumentBuilder docBuilder; Document xmlDoc = null; try { docBuilder = docFactory.newDocumentBuilder(); xmlDoc = docBuilder.parse(new InputSource("./LC480.xml")); } catch (Exception ex) { Exceptions.printStackTrace(ex); } // Setup the objects need for the import // Setup the Run object // Run run = new RunImpl(); // Set the run name and date Run run = new RunImpl(); // Retrieve the xml file // For development purposes, just use an example xml file // File lcRdmlFile = IOUtilities.openXmlFile("Lightcycler XML Data Import"); // if (lcRdmlFile == null) { // return null; // } // Setup the profile arraylists ArrayList<SampleProfile> sampleProfileList = Lists.newArrayList(); ArrayList<CalibrationProfile> calbnProfileList = Lists.newArrayList(); // Determine the strandedness of the majority of the Targets...too bad that this is not provided // by the instrument TargetStrandedness targetStrandedness = RunImportUtilities.isTheTargetSingleStranded(); // Get the all of the profile nodes NodeList profileNodeList = xmlDoc.getElementsByTagName("series"); // Cycle through all of the profile nodes for (int i = 0; i < profileNodeList.getLength(); i++) { // TODO determine whether this profile is sample or calibration Profile profile = createProfileType(run); Element profileElement = (Element) profileNodeList.item(i); String wellLabel = profileElement.getAttribute("title"); // TODO parse the well label, sample and amplicon name from the wellLabel NodeList cycleList = profileElement.getElementsByTagName("point"); // Collect and set the Fc reading profile.setFcReadings(retrieveFcReadings(cycleList)); if (CalibrationProfile.class.isAssignableFrom(profile.getClass())) { CalibrationProfile calProfile = (CalibrationProfile) profile; calbnProfileList.add(calProfile); } else { SampleProfile sampleProfile = (SampleProfile) profile; sampleProfileList.add(sampleProfile); } } return null; }
/** * This conducts both nonlinear regression-derived Fb subtraction and baseline slope correction. * * @param profile */ private void conductBaselineCorrection() { // Start with correcting for the NR-derived Fb slope double[] rawFcReadings = profile.getRawFcReadings(); double[] processedFcDataset = new double[rawFcReadings.length]; // The new optimized Fc dataset // This assumes that nonlinear regression has been conducted AND it was successfully completed double nrFb = profile.getNrFb(); // The regression derived Fb double nrFbSlope = profile.getNrFbSlope(); // The regression-derived Fb slope for (int i = 0; i < processedFcDataset.length; i++) { processedFcDataset[i] = rawFcReadings[i] - nrFb - (nrFbSlope * (i + 1)); } profile.setFcReadings(processedFcDataset); }
/** * Retrieves the current LRE parameters from the Profile * * @param profile * @return */ private LreParameters getLreParameters() { // Setup the initial parameters LreParameters lreDerivedParam = new LreParameters(); // Testing indicates that if Fb=0 the NR fails if (profile.getNrFb() == 0) { lreDerivedParam.setFb(profile.getFb()); // This Fb is derived from the average of cycles 4-9 } else { lreDerivedParam.setFb(profile.getNrFb()); } lreDerivedParam.setEmax(profile.getEmax()); // Current LRE-derived Emax lreDerivedParam.setFmax(profile.getFmax()); // Current LRE-derived Fmax lreDerivedParam.setFo(profile.getAvFo()); // Current LRE-derived average Fo lreDerivedParam.setFbSlope(profile.getNrFbSlope()); // Current Fb slope return lreDerivedParam; }
private boolean testIfRegressionWasSuccessful() { // **** TODO Design a more effective scheme to test for NR // success // Test if the regression analysis was successful based on the LRE line R2 Double r2 = profile.getR2(); Double emaxNR = profile.getNrEmax(); // Very, very crude approach if (r2 < 0.8 || r2.isNaN() || emaxNR < 0.3) { // Error dialog DISABLED as it is extremely irrating // Toolkit.getDefaultToolkit().beep(); // SimpleDateFormat sdf = new SimpleDateFormat("dMMMyy"); // JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), // "The nonlinear regression analysis has failed for well '" // + sdf.format(profile.getRunDate()) + ": " // + profile.getWellLabel() + "'.\n" // + "LRE analysis will be conducted without baseline-slope correction", // "Failed to Apply Nonlinear Regression.", // JOptionPane.ERROR_MESSAGE); // Reset the LRE window using Fb profile.setWasNonlinearRegressionSuccessful(false); profile.setNrFb(0); profile.setNrFbSlope(0); // Return to average Fb background subtraction LreWindowSelector.substractBackgroundUsingAvFc(profile); // Recalculate the LRE parameters prfSum.update(); // Reinitialize the profile List<LreWindowSelectionParameters> l = prfSum.getDatabase().getAllObjects(LreWindowSelectionParameters.class); LreWindowSelectionParameters parameters = l.get(0); LreAnalysisService lreAnalService = Lookup.getDefault().lookup(LreAnalysisService.class); lreAnalService.lreWindowInitialization(prfSum, parameters); return false; } profile.setWasNonlinearRegressionSuccessful(true); return true; }
/** * Generates an optimized working Fc dataset via nonlinear regression to derived Fb and Fb-slope * using the current LRE window. * * <p>Nonlinear regression is conducted using Emax, Fmax and Fo derived from the current LRE * window, from WHICH values for Fb and Fb-slope are determined. These are then used to calculate * a new working Fc dataset, followed by recalculation of the LRE parameters. This process * repeated 3 times from which an average Fb and Fb-slope are then determined and a final * optimized working Fc dataset generated. This is followed by a final recalculation of the LRE * parameters to determine final values for Emax, Fmax and Fo. THIS DOES THIS INCLUDE ANY * MODIFICATION TO THE LRE WINDOW. * * <p>Note also that the LRE parameters are updated and the modified Profile is saved, which * includes initialization of a new Cycle linked list, so any calling function must reset its * runner. * * @param prfSum the ProfileSummary encapsulating the Profile * @return true if nonlinear regression analysis was successful or false if it failed */ public boolean generateOptimizedFcDatasetUsingNonliearRegression(ProfileSummary prfSum) { this.prfSum = prfSum; profile = prfSum.getProfile(); // The profile must have a valid LRE window if (!profile.hasAnLreWindowBeenFound()) { return false; } // Need to trim the profile in order to avoid aberrancies within early cycles and within the // plateau phase // Exclude the first three cycles int firstCycle = 4; // Start at cycle 4 // Use the top of the LRE window as the last cycle included in the regression analysis******THIS // IS VERY IMPORTANT double[] fcArray = profile.getRawFcReadings(); int lastCycle = 0; if (prfSum.getLreWindowEndCycle() != null) { lastCycle = prfSum.getLreWindowEndCycle().getCycNum(); } else { return false; } int numberOfCycles = lastCycle - firstCycle + 1; // Construct the trimmed Fc dataset TreeMap<cycle number, Fc reading> TreeMap<Integer, Double> profileMap = new TreeMap<Integer, Double>(); for (int i = 0; i < numberOfCycles; i++) { profileMap.put(firstCycle + i, fcArray[firstCycle - 1 + i]); } // Run NR once to grossly stablize the LRE-derived parameters LreParameters lreDerivedParam = getLreParameters(); LreParameters optParam = nrService.conductNonlinearRegression(lreDerivedParam, profileMap); // Reinitialize the LRE-derived parameters // First Reset nonlinear regression-derived Fb and Fb-slope within the profile profile.setNrFb(optParam.getFb()); profile.setNrFbSlope(optParam.getFbSlope()); // Generate a new optimized Fc dataset based on NR-derived Fb and Fb-slope conductBaselineCorrection(); // Updating the ProfileSummary updates the LRE-derived parameters within the Profile with no // change to the LRE window // However, this assumes that the NR was successful prfSum.update(); // Reset the LRE-derived paramaters lreDerivedParam = getLreParameters(); // Run the regression analysis 10 times to determine the average and SD // This is necessary due to the poor performance of Peter Abeles’s EJML implementation int numberOfIterations = 3; ArrayList<Double> emaxArray = new ArrayList<Double>(); ArrayList<Double> fbArray = new ArrayList<Double>(); ArrayList<Double> foArray = new ArrayList<Double>(); ArrayList<Double> fmaxArray = new ArrayList<Double>(); ArrayList<Double> fbSlopeArray = new ArrayList<Double>(); double emaxSum = 0; double fbSum = 0; double foSum = 0; double fmaxSum = 0; double fbSlopeSum = 0; for (int i = 0; i < numberOfIterations; i++) { optParam = nrService.conductNonlinearRegression(lreDerivedParam, profileMap); emaxArray.add(optParam.getEmax()); emaxSum += optParam.getEmax(); fbArray.add(optParam.getFb()); fbSum += optParam.getFb(); foArray.add(optParam.getFo()); foSum += optParam.getFo(); fmaxArray.add(optParam.getFmax()); fmaxSum += optParam.getFmax(); fbSlopeArray.add(optParam.getFbSlope()); fbSlopeSum += optParam.getFbSlope(); // Reinitialize the LRE-derived parameters // First reset nonlinear regression-derived Fb and Fb-slope within the profile profile.setNrFb(optParam.getFb()); profile.setNrFbSlope(optParam.getFbSlope()); // Generate a new optimized Fc dataset conductBaselineCorrection(); // Update the LRE-derived parameters within the Profile prfSum.update(); // Retrieve the new LRE parameters lreDerivedParam = getLreParameters(); } // Set the average for each parameter into the Profile // This allows the final recalculation of the LRE parameters based on the average Fb and // Fb-slope profile.setNrEmax(emaxSum / numberOfIterations); profile.setNrFb(fbSum / numberOfIterations); profile.setNrFo(foSum / numberOfIterations); profile.setNrFmax(fmaxSum / numberOfIterations); profile.setNrFbSlope(fbSlopeSum / numberOfIterations); // Determine and set the parameter SD profile.setNrEmaxSD(MathFunctions.calcStDev(emaxArray)); profile.setNrFbSD(MathFunctions.calcStDev(fbArray)); profile.setNrFoSD(MathFunctions.calcStDev(foArray)); profile.setNrFmaxSD(MathFunctions.calcStDev(fmaxArray)); profile.setNrFbSlopeSD(MathFunctions.calcStDev(fbSlopeArray)); // Recaculate the optimized Fc dataset using the average NR-derived Fb and Fb-slope conductBaselineCorrection(); // Update the LRE parameters prfSum.update(); return testIfRegressionWasSuccessful(); }