public NutrientInputs GetNutrientInputs(NutrientInputs nutrientInputs) { FarmManure mymanure = _ud.GetFarmManure(Convert.ToInt32(manure)); ConversionFactor _cf = _sd.GetConversionFactor(); decimal potassiumAvailabilityFirstYear = _cf.potassiumAvailabilityFirstYear; decimal potassiumAvailabilityLongTerm = _cf.potassiumAvailabilityLongTerm; decimal potassiumKtoK2Oconversion = _cf.potassiumKtoK2Oconversion; decimal phosphorousAvailabilityFirstYear = _cf.phosphorousAvailabilityFirstYear; decimal phosphorousAvailabilityLongTerm = _cf.phosphorousAvailabilityLongTerm; decimal phosphorousPtoP2O5Kconversion = _cf.phosphorousPtoP2O5Kconversion; decimal lbPerTonConversion = _cf.lbPerTonConversion; decimal tenThousand = 10000; // get conversion factor for selected units to lb/ac Unit myunit = _sd.GetUnit(applicationRateUnits); decimal conversion = myunit.conversion_lbton; // for solid manures specified in cubic yards per ac, convert application rate to tons/ac if (myunit.id == 6 && mymanure.solid_liquid.ToUpper() == "SOLID") { Manure manure = _sd.GetManure(mymanure.manureId.ToString()); applicationRate = applicationRate * manure.cubic_Yard_Conversion; } // get potassium first year nutrientInputs.K2O_FirstYear = Convert.ToInt32(decimal.Multiply(applicationRate, mymanure.potassium) * lbPerTonConversion * potassiumKtoK2Oconversion * potassiumAvailabilityFirstYear * conversion); // get potassium long term nutrientInputs.K2O_LongTerm = Convert.ToInt32(decimal.Multiply(applicationRate, mymanure.potassium) * lbPerTonConversion * potassiumKtoK2Oconversion * potassiumAvailabilityLongTerm * conversion); // get phosphorous first year nutrientInputs.P2O5_FirstYear = Convert.ToInt32(decimal.Multiply(applicationRate, mymanure.phosphorous) * lbPerTonConversion * phosphorousPtoP2O5Kconversion * phosphorousAvailabilityFirstYear * conversion); // get phosphorous long term nutrientInputs.P2O5_LongTerm = Convert.ToInt32(decimal.Multiply(applicationRate, mymanure.phosphorous) * lbPerTonConversion * phosphorousPtoP2O5Kconversion * phosphorousAvailabilityLongTerm * conversion); // get N values // Organic N% = Total N% - NH4-N ppm / 10,000 decimal organicN = mymanure.nitrogen - (Convert.ToDecimal(mymanure.ammonia) / tenThousand); NOrganicMineralizations nOrganicMineralizations = new NOrganicMineralizations(); int regionid = _ud.FarmDetails().farmRegion.Value; Region region = _sd.GetRegion(regionid); nOrganicMineralizations = GetNMineralization(mymanure.id, region.locationid); nOrganicMineralizations.OrganicN_FirstYear = firstYearOrganicNAvailablityPct / 100; // get data from screen //decimal ammoniaRetention = GetAmmoniaRetention(mymanure.id, Convert.ToInt32(applicationSeason)); decimal ammoniaRetention = ammoniaNRetentionPct / 100; // get data from screen // N 1st year lb/ton = [NH4-N ppm/10,000 * NH4 retention + NO3-N/10,000 + Organic N % * 1st yr Mineralization] * 20 decimal a = decimal.Divide(mymanure.ammonia, tenThousand) * ammoniaRetention; decimal b1 = decimal.Multiply(organicN, nOrganicMineralizations.OrganicN_FirstYear); //E07US20 decimal c1 = a + b1 + Convert.ToDecimal(mymanure.nitrate) / tenThousand; decimal N_Firstyear = decimal.Multiply(c1, lbPerTonConversion); nutrientInputs.N_FirstYear = Convert.ToInt32(applicationRate * N_Firstyear * conversion); // same for long term decimal b2 = decimal.Multiply(organicN, nOrganicMineralizations.OrganicN_LongTerm); //E07US20 decimal c2 = a + b2 + Convert.ToDecimal(mymanure.nitrate) / tenThousand; decimal N_LongTerm = decimal.Multiply(c2, lbPerTonConversion); nutrientInputs.N_LongTerm = Convert.ToInt32(applicationRate * N_LongTerm * conversion); return(nutrientInputs); }
public List <BalanceMessages> DetermineBalanceMessages(string fieldName) { List <BalanceMessages> messages = new List <BalanceMessages>(); bool legume = false; string message = string.Empty; BalanceMessages bm = new BalanceMessages(); //get soil test values ConversionFactor _cf = _sd.GetConversionFactor(); //get the chemical balances ChemicalBalances cb = GetChemicalBalances(fieldName); //determine if a legume is included in the crops List <FieldCrop> fieldCrops = _ud.GetFieldCrops(fieldName); if (fieldCrops.Count > 0) { foreach (var _crop in fieldCrops) { Crop crop = _sd.GetCrop(Convert.ToInt16(_crop.cropId)); if (crop.n_recommcd == 1) // no nitrogen need to be added { legume = true; } } if (legume) { // get sum of agronomic N for manure, fertilizer and other for field // sum the above number with the crop removal N // use the resulting number to determine message long LegumeAgronomicN = GetLegumeAgronomicN(fieldName); int LegumeRemovalN = GetLegumeRemovalN(fieldName); bm = _sd.GetMessageByChemicalBalance("AgrN", LegumeAgronomicN + LegumeRemovalN, legume); if (bm != null) { messages.Add(bm); } } else { bm = _sd.GetMessageByChemicalBalance("AgrN", chemicalBalances.balance_AgrN, legume); if (bm != null) { messages.Add(bm); } } bm = _sd.GetMessageByChemicalBalance("AgrP2O5", chemicalBalances.balance_AgrP2O5, legume); if (bm != null) { messages.Add(bm); } bm = _sd.GetMessageByChemicalBalance("AgrK2O", chemicalBalances.balance_AgrK2O, legume); if (bm != null) { messages.Add(bm); } bm = _sd.GetMessageByChemicalBalance("CropN", chemicalBalances.balance_CropN, legume); if (bm != null) { messages.Add(bm); } bm = _sd.GetMessageByChemicalBalance("CropP2O5", chemicalBalances.balance_CropP2O5, legume); if (bm != null) { messages.Add(bm); } bm = _sd.GetMessageByChemicalBalance("CropK2O", chemicalBalances.balance_CropK2O, legume); if (!string.IsNullOrEmpty(bm.Chemical)) { messages.Add(bm); } bm = _sd.GetMessageByChemicalBalance("AgrP2O5CropP2O5", chemicalBalances.balance_AgrP2O5, chemicalBalances.balance_CropP2O5, "CropP2O5"); if (bm != null) { messages.Add(bm); } } return(messages); }
// This processing detemines the N P K values in lb per acre for the fertilizer select and appricatio rate/density etc. public FertilizerNutrients GetFertilizerNutrients() { FertilizerNutrients fn = new FertilizerNutrients(); // get the fertilizer N P K % values from fertlizer look up // for dry fertilizers // N (lb/ac) = Application rate converted to lb/ac * N % // P and K same as above // for wet fertilizers // N (lb/ac) = Application rate converted to lb/ac * N% * Density converted to lb / imp gallons // decimal applicationRateConversion = 0; decimal densityInSelectedUnit = 0; decimal densityUnitConversion = 0; Fertilizer _fertilizer = _sd.GetFertilizer(FertilizerId.ToString()); if ((CustomFertilizer && FertilizerType == "dry") || (!CustomFertilizer && _fertilizer.dry_liquid == "dry")) { densityUnitConversion = 1; switch (ApplicationRateUnits) { case 1: // application rate in lb/ac no conversion required applicationRateConversion = 1; break; case 2: // application rate in kg/ha, convert to lb/ac ConversionFactor _cf = _sd.GetConversionFactor(); applicationRateConversion = _cf.kgperha_lbperac_conversion; break; case 7: // application rate in lb/100 ft squared, convert to lb/ac ConversionFactor _cf1 = _sd.GetConversionFactor(); applicationRateConversion = _cf1.lbper1000ftsquared_lbperac_conversion; break; } } else //use liquid fertilizer { FertilizerUnit _fU = _sd.GetFertilizerUnit(ApplicationRateUnits); applicationRateConversion = _fU.conv_to_impgalperac; if (CustomFertilizer) { densityInSelectedUnit = Density; } else { LiquidFertilizerDensity _lfd = _sd.GetLiquidFertilizerDensity(FertilizerId, DensityUnits); densityInSelectedUnit = _lfd.value; } DensityUnit _du = _sd.GetDensityUnit(DensityUnits); densityUnitConversion = _du.convfactor * densityInSelectedUnit; } fn.fertilizer_N = ApplicationRate * decimal.Divide(userN, 100) * applicationRateConversion * densityUnitConversion; fn.fertilizer_P2O5 = ApplicationRate * decimal.Divide(userP2o5, 100) * applicationRateConversion * densityUnitConversion; fn.fertilizer_K2O = ApplicationRate * decimal.Divide(userK2o, 100) * applicationRateConversion * densityUnitConversion; return(fn); }
public CropRequirementRemoval GetCropRequirementRemoval() { decimal n_removal = 0; ConversionFactor _cf = _sd.GetConversionFactor(); CropRequirementRemoval crr = new CropRequirementRemoval(); Crop crop = _sd.GetCrop(cropid); // For testing we're using Soil Test Kelowna of 65ppm, should actually by 100+ (say 101) // // Nutrient removal // P2O5 = crop.cropremovalfactor_P2O5 * yield // K2O = crop.cropremovalfactor_K2O * yield // N = crop.cropremovalfactor_N * yield // if crude_protien exists and is not default // crop.cropremovalfactor_N = (crude protien / (0.625 * 0.5)) // N = crop.cropremovalfactor_N * yield // else // N = crop.cropremovalfactor_N * yield // // Note for Cover crops (only) // if Cover Crop harvested // don't change numbers // if Cover crop not harvested // set all removal amts to zero if (!crudeProtien.HasValue || (crudeProtien.HasValue && crudeProtien.Value == 0)) { decimal tmpDec; if (decimal.TryParse(crop.cropremovalfactor_N.ToString(), out tmpDec)) { n_removal = tmpDec * yield; } else { n_removal = 0; } } else { n_removal = decimal.Divide(Convert.ToDecimal(crudeProtien), (_cf.n_protein_conversion * _cf.unit_conversion)) * yield; } crr.P2O5_Removal = Convert.ToInt32(crop.cropremovalfactor_P2O5 * yield); crr.K2O_Removal = Convert.ToInt32(crop.cropremovalfactor_K2O * yield); crr.N_Removal = Convert.ToInt32(n_removal); if (coverCropHarvested.HasValue && coverCropHarvested.Value == false) { crr.P2O5_Removal = 0; crr.K2O_Removal = 0; crr.N_Removal = 0; } // Crop Requirement // P205 // get region.soil_test_phospherous_region_cd // get phosphorous_crop_group_region_cd = crop_stp_regioncd(cropid, region.soil_test_phospherous_region_cd) // get stp_kelowna_range.id usign default ST Kelowna (65) between range_low and range_high // get P2O5 recommedation = stp_recommend(stp_kelowna_range.id, region.soil_test_phospherous_region_cd, phosphorous_crop_group_region_cd) // // same as above for K2O // // For N // Look up crop.n_recommcd // if 0 or 1 // N = crop.n_recomm_lbperac // if 2 // same as N removal // if 3 // get default yield = cropyield(cropid, locationid) // N = (yield / default yield) * crop.n_recomm_lbperac int regionid = _ud.FarmDetails().farmRegion.Value; Region region = _sd.GetRegion(regionid); Field fld = _ud.GetFieldDetails(fieldName); if (fld.soilTest == null) { fld.soilTest = new SoilTest(); DefaultSoilTest dt = _sd.GetDefaultSoilTest(); fld.soilTest.valNO3H = dt.nitrogen; fld.soilTest.ValP = dt.phosphorous; fld.soilTest.valK = dt.potassium; fld.soilTest.valPH = dt.pH; fld.soilTest.ConvertedKelownaK = dt.convertedKelownaK; fld.soilTest.ConvertedKelownaP = dt.convertedKelownaP; } int _STP = fld.soilTest.ConvertedKelownaP; if (_STP == 0) { _STP = _cf.defaultSoilTestKelownaP; } int _STK = fld.soilTest.ConvertedKelownaK; if (fld.soilTest.ConvertedKelownaK == 0) { _STK = _cf.defaultSoilTestKelownaK; } // p2o5 recommend calculations CropSTPRegionCd cropSTPRegionCd = _sd.GetCropSTPRegionCd(cropid, region.soil_test_phospherous_region_cd); int? phosphorous_crop_group_region_cd = cropSTPRegionCd.phosphorous_crop_group_region_cd; STPKelownaRange sTPKelownaRange = _sd.GetSTPKelownaRangeByPpm(_STP); int stp_kelowna_range_id = sTPKelownaRange.id; if (phosphorous_crop_group_region_cd == null) { crr.P2O5_Requirement = 0; } else { STPRecommend sTPRecommend = _sd.GetSTPRecommend(stp_kelowna_range_id, region.soil_test_phospherous_region_cd, Convert.ToInt16(phosphorous_crop_group_region_cd)); crr.P2O5_Requirement = Convert.ToInt32(Convert.ToDecimal(sTPRecommend.p2o5_recommend_kgperha) * _cf.kgperha_lbperac_conversion); } // k2o recommend calculations CropSTKRegionCd cropSTKRegionCd = _sd.GetCropSTKRegionCd(cropid, region.soil_test_potassium_region_cd); int? potassium_crop_group_region_cd = cropSTKRegionCd.potassium_crop_group_region_cd; STKKelownaRange sTKKelownaRange = _sd.GetSTKKelownaRangeByPpm(_STK); int stk_kelowna_range_id = sTKKelownaRange.id; if (potassium_crop_group_region_cd == null) { crr.K2O_Requirement = 0; } else { STKRecommend sTKRecommend = _sd.GetSTKRecommend(stk_kelowna_range_id, region.soil_test_potassium_region_cd, Convert.ToInt16(potassium_crop_group_region_cd)); crr.K2O_Requirement = Convert.ToInt32(Convert.ToDecimal(sTKRecommend.k2o_recommend_kgperha) * _cf.kgperha_lbperac_conversion); } // n recommend calculations -note the excel n_recommd are zero based, the static data is 1 based switch (crop.n_recommcd) { case 1: crr.N_Requirement = Convert.ToInt16(crop.n_recomm_lbperac); break; case 2: crr.N_Requirement = Convert.ToInt16(crop.n_recomm_lbperac); break; case 3: crr.N_Requirement = crr.N_Removal; break; case 4: CropYield cropYield = _sd.GetCropYield(cropid, region.locationid); if (cropYield.amt != null) { crr.N_Requirement = Convert.ToInt16(decimal.Divide(yield, Convert.ToDecimal(cropYield.amt)) * crop.n_recomm_lbperac); } else { crr.N_Requirement = 0; } break; } // if a previous crop has been ploughed dowm account for the N in the field (passed in as a credit) crr.N_Requirement = crr.N_Requirement - nCredit; // only reduce to 0 crr.N_Requirement = (crr.N_Requirement < 0) ? 0 : crr.N_Requirement; return(crr); }