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