@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();
  }