private void buttonOptimize_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; calcStats cStat = new calcStats(); long strSamp, sgSamp, sgSamp1, sgSamp2; double combWtCV, strCV, strCalcError, sgCV, sgCalcError, totVolume; // get sale volume double tVolume = cdStratumStats.Sum(P => P.TotalVolume); if (tVolume == 0) { MessageBox.Show("No volume. Cannot calculate sample sizes.", "Warning"); return; } if (mySale.DefaultUOM == "01") totVolume = tVolume * 1000.0; else totVolume = tVolume * 100.0; // get weighted sale cv double saleCV = 0; long strSamp1 = 0; long strSamp2 = 0; double sumError = 0; double sumVolume = 0; double tStrVol; foreach (StratumStatsDO thisStrStats in cdStratumStats) { if (mySale.DefaultUOM == "01") tStrVol = thisStrStats.TotalVolume * 1000.0; else tStrVol = thisStrStats.TotalVolume * 100.0; int stage = cStat.isTwoStage(thisStrStats.Method); // single stage wted CV if (stage == 10 || stage == 11 || stage == 21) { saleCV += thisStrStats.WeightedCV1 * (tStrVol / totVolume); } // 2 stage wted CV else { combWtCV = (thisStrStats.WeightedCV1 + thisStrStats.WeightedCV2) / 2.0; saleCV += combWtCV * (tStrVol / totVolume); } } if (saleCV == 0) { MessageBox.Show("Cannot calculate weighted sale CV.", "Warning"); return; } //float saleCV = cdStratumStats.Sum(P => ((P.WeightedCV1 * P.TotalVolume)/totVolume)); double saleOptError = Convert.ToSingle(numericUpDown1.Value); // calculate sale level sample size long saleCalcSamples = cStat.getSampleSize(saleOptError, saleCV); // calculate sale error using t-value of 2 double saleCalcError = cStat.getSampleError(saleCV, saleCalcSamples, 2.0); // correct sample size using correct t-value double saleSamples = cStat.checkTValueError(saleCV, saleCalcSamples, saleCalcError); // prorate to strata foreach (StratumStatsDO thisStrStats in cdStratumStats) { int stage = cStat.isTwoStage(thisStrStats.Method); long strSample1 = 0; long strSample2 = 0; double wtErr = 0; float acres = thisStrStats.TotalAcres; float stTpa = thisStrStats.TreesPerAcre; long stN = (long)Math.Ceiling(stTpa * acres); // single stage wted CV if (mySale.DefaultUOM == "01") tStrVol = thisStrStats.TotalVolume * 1000.0; else tStrVol = thisStrStats.TotalVolume * 100.0; if (stage == 10 || stage == 21) { strCV = thisStrStats.WeightedCV1 * (tStrVol / totVolume); strSamp = Convert.ToInt32((strCV / saleCV) * saleSamples); strCalcError = cStat.getSampleError(thisStrStats.WeightedCV1, strSamp, 2.0); // correct for t-value strSamp1 = cStat.checkTValueError(thisStrStats.WeightedCV1, strSamp, strCalcError); } else if (stage == 11) { strCV = thisStrStats.WeightedCV1 * (tStrVol / totVolume); strSamp = Convert.ToInt32((strCV / saleCV) * saleSamples); strCalcError = cStat.getSampleError(thisStrStats.WeightedCV1, strSamp, 2.0); // correct for t-value strSamp1 = cStat.checkTValueError(thisStrStats.WeightedCV1, strSamp, strCalcError, stN); } // 2 stage wted CV else { combWtCV = (thisStrStats.WeightedCV1 + thisStrStats.WeightedCV2) / 2.0; strCV = combWtCV * (tStrVol / totVolume); strSamp = Convert.ToInt32((strCV / saleCV) * saleSamples); strCalcError = cStat.getSampleError(combWtCV, strSamp, 2.0); cStat.getTwoStageSampleSize(thisStrStats.WeightedCV1, thisStrStats.WeightedCV2, strCalcError); // correct for t-value strSamp2 = cStat.sampleSize2; strSamp1 = cStat.checkTValueError2Stage(thisStrStats.WeightedCV1, thisStrStats.WeightedCV2, cStat.sampleSize1, cStat.sampleSize2, strCalcError); } List<SampleGroupStatsDO> mySgStats = new List<SampleGroupStatsDO>(cdDAL.Read<SampleGroupStatsDO>("SampleGroupStats", "Where StratumStats_CN = ?", thisStrStats.StratumStats_CN)); long sgSamp2Stage1 = 0; long sgSamp2Stage2 = 0; foreach (SampleGroupStatsDO thisSgStats in mySgStats) { float sgTpa = thisSgStats.TreesPerAcre; long sgN = (long)Math.Ceiling(sgTpa * acres); // prorate to sample groups if (stage == 11) { sgCV = thisSgStats.CV1 * (thisSgStats.VolumePerAcre / thisStrStats.VolumePerAcre); sgSamp = Convert.ToInt32((sgCV / thisStrStats.WeightedCV1) * strSamp1); sgCalcError = cStat.getSampleError(thisSgStats.CV1, sgSamp, 2.0); // correct for t-value sgSamp1 = cStat.checkTValueError(thisSgStats.CV1, sgSamp, sgCalcError, sgN); if (sgSamp1 < 3) sgSamp1 = 3; sgSamp2 = 0; sgCalcError = cStat.getSampleError(thisSgStats.CV1, sgSamp1, 0, sgN); } else if (stage == 21) { sgCV = thisSgStats.CV1 * (thisSgStats.VolumePerAcre / thisStrStats.VolumePerAcre); sgSamp = Convert.ToInt32((sgCV / thisStrStats.WeightedCV1) * strSamp1); sgCalcError = cStat.getSampleError(thisSgStats.CV1, sgSamp, 2.0); // correct for t-value sgSamp1 = cStat.checkTValueError(thisSgStats.CV1, sgSamp, sgCalcError); if (sgSamp1 < 3) sgSamp1 = 3; sgSamp2 = (long)(thisSgStats.TreesPerPlot * sgSamp1); sgCalcError = cStat.getSampleError(thisSgStats.CV1, sgSamp1, 0); } else if (stage == 10) { sgSamp1 = Convert.ToInt32(thisSgStats.TreesPerAcre * thisStrStats.TotalAcres); sgSamp2 = 0; sgCalcError = 0; } else { sgCV = thisSgStats.CV2 * (thisSgStats.VolumePerAcre / thisStrStats.VolumePerAcre); sgSamp2 = Convert.ToInt32((sgCV / thisStrStats.WeightedCV2) * strSamp2); if (sgSamp2 < 3) sgSamp2 = 3; sgCV = thisSgStats.CV1 * (thisSgStats.VolumePerAcre / thisStrStats.VolumePerAcre); sgSamp1 = Convert.ToInt32((sgCV / thisStrStats.WeightedCV1) * strSamp1); if (sgSamp1 < 3) sgSamp1 = 3; if (stage == 12) { if (sgSamp2 > sgSamp1) sgSamp1 = sgSamp2; } else { if (sgSamp1 > sgSamp2Stage1) sgSamp2Stage1 = sgSamp1; } thisSgStats.SampleSize1 = sgSamp1; thisSgStats.SampleSize2 = sgSamp2; sgCalcError = cStat.getTwoStageError(thisSgStats.CV1, thisSgStats.CV2, sgSamp1, sgSamp2); } thisSgStats.SampleSize1 = sgSamp1; thisSgStats.SampleSize2 = sgSamp2; // update errors, frequency, KZ, BigBAF if (thisStrStats.Method == "STR") { thisSgStats.SamplingFrequency = Convert.ToInt32((thisSgStats.TreesPerAcre * thisStrStats.TotalAcres) / sgSamp1); strSample1 += sgSamp1; } else if (thisStrStats.Method == "S3P") { thisSgStats.SamplingFrequency = Convert.ToInt32((thisSgStats.TreesPerAcre * thisStrStats.TotalAcres) / sgSamp1); strSample1 += sgSamp1; strSample2 += sgSamp2; } else if (thisStrStats.Method == "100") { thisSgStats.SamplingFrequency = 1; strSample1 += sgSamp1; } else if (thisStrStats.Method == "3P") { thisSgStats.KZ = Convert.ToInt32((thisSgStats.VolumePerAcre * thisStrStats.TotalAcres) / sgSamp1); strSample1 += sgSamp1; } else if (thisStrStats.Method == "S3P") { if (thisSgStats.TreesPerAcre > 0) thisSgStats.KZ = Convert.ToInt32(((thisSgStats.VolumePerAcre / thisSgStats.TreesPerAcre * sgSamp1) / sgSamp2)); else thisSgStats.KZ = 1; strSample1 += sgSamp1; strSample2 += sgSamp2; } else if (thisStrStats.Method == "PNT" || thisStrStats.Method == "FIX") { strSample1 = sgSamp1; strSample2 = sgSamp2; } // calc sg error if(stage != 22) { if (stage == 11) { thisSgStats.SgError = Convert.ToSingle(Math.Round(cStat.getSampleError(thisSgStats.CV1,sgSamp1, 0, sgN), 2)); } else if (stage == 21) { thisSgStats.SgError = Convert.ToSingle(Math.Round(cStat.getSampleError(thisSgStats.CV1, sgSamp1, 0), 2)); } else if (stage == 12 || stage == 22) { thisSgStats.SgError = Convert.ToSingle(Math.Round(cStat.getTwoStageError(thisSgStats.CV1, thisSgStats.CV2, sgSamp1, sgSamp2), 2)); } // calc combined stratum error wtErr += (double)Math.Pow((thisSgStats.SgError * (thisSgStats.VolumePerAcre * thisStrStats.TotalAcres)), 2); } thisSgStats.Save(); } if (stage == 22) { //loop back through foreach (SampleGroupStatsDO thisSgStats in mySgStats) { // set each sample size to sgSamp2Stage strSample1 = sgSamp2Stage1; sgSamp2Stage2 = thisSgStats.SampleSize2; strSample2 += sgSamp2Stage2; // set frequencies if (thisStrStats.Method == "FCM") { thisSgStats.SamplingFrequency = Convert.ToInt32((thisSgStats.TreesPerPlot * sgSamp2Stage1) / sgSamp2Stage2); } else if (thisStrStats.Method == "PCM") { thisSgStats.SamplingFrequency = Convert.ToInt32((thisSgStats.TreesPerPlot * sgSamp2Stage1) / sgSamp2Stage2); thisSgStats.BigBAF = Convert.ToSingle(thisSgStats.SamplingFrequency * thisStrStats.BasalAreaFactor); } else if (thisStrStats.Method == "P3P") { thisSgStats.KZ = Convert.ToInt32((thisSgStats.TreesPerPlot * sgSamp2Stage1 * thisSgStats.AverageHeight) / sgSamp2Stage2); } else if (thisStrStats.Method == "F3P" || thisStrStats.Method == "3PPNT") { if (thisSgStats.TreesPerAcre > 0) thisSgStats.KZ = Convert.ToInt32((thisSgStats.TreesPerPlot * sgSamp2Stage1 * (thisSgStats.VolumePerAcre / thisSgStats.TreesPerAcre)) / sgSamp2Stage2); else thisSgStats.KZ = 1; } thisSgStats.SampleSize1 = sgSamp2Stage1; thisSgStats.SgError = Convert.ToSingle(Math.Round(cStat.getTwoStageError(thisSgStats.CV1, thisSgStats.CV2, sgSamp2Stage1, sgSamp2Stage2), 2)); // calc combined stratum error thisSgStats.Save(); wtErr += (double)Math.Pow((thisSgStats.SgError * (thisSgStats.VolumePerAcre * thisStrStats.TotalAcres)), 2); } } // Update Stratum if(mySale.DefaultUOM == "01") thisStrStats.StrError = (float)(Math.Sqrt(wtErr) / (tStrVol)); else thisStrStats.StrError = (float)(Math.Sqrt(wtErr) / (tStrVol)); thisStrStats.SampleSize1 = strSample1; thisStrStats.SampleSize2 = strSample2; if (stage > 20) { thisStrStats.PlotSpacing = (int)Math.Floor(Math.Sqrt((thisStrStats.TotalAcres * 43560) / strSample1)); } thisStrStats.Save(); sumError += (double)Math.Pow((tStrVol * thisStrStats.StrError),2); sumVolume += tStrVol; } // Update Sale Error and Cost getSaleError(); //double saleError = Math.Sqrt(sumError) / sumVolume; //textBoxError.Text = (Math.Round(saleError, 2)).ToString(); //textBoxVolume.Text = (Math.Round(tVolume, 0)).ToString(); Cursor.Current = this.Cursor; return; }