def test_pmodel_class_c3(request, values, soilmstress, ftemp_kphio, luevcmax_method, variables): # Get the main vars kwargs = {k: values[v] for k, v in variables.items()} if soilmstress: soilmstress = pmodel.calc_soilmstress(values['soilm_sc'], values['meanalpha_sc']) else: soilmstress = None ret = pmodel.PModel(**kwargs, kphio=0.05, soilmstress=soilmstress, do_ftemp_kphio=ftemp_kphio, method_jmaxlim=luevcmax_method) # Find the expected values, extracting the combination from the request name = request.node.name name = name[(name.find('[') + 1):-1] expected = values['rpmodel-c3-' + name + '-unitiabs'] # Test values - two values calculated in main rpmodel function # so can only test here - ci and iwue assert np.allclose(ret.iwue, expected['iwue']) assert np.allclose(ret.optchi.ci, expected['ci']) # - and six values that are scaled by IABS - rpmodel enforces scaling # where PModel can do it post hoc from unit_iabs values, so two # rpmodel runs are used to test the unit values and scaled. assert np.allclose(ret.unit_iabs.lue, expected['lue']) assert np.allclose(ret.unit_iabs.vcmax, expected['vcmax']) assert np.allclose(ret.unit_iabs.vcmax25, expected['vcmax25']) assert np.allclose(ret.unit_iabs.rd, expected['rd']) assert np.allclose(ret.unit_iabs.gs, expected['gs']) # TODO - Numerical instability in the Jmax calculation - as denominator # approaches 1, results --> infinity unpredictably with rounding # so currently excluding Jmax in combinations where this occurs. if 'none-fkphio-off-sm-off' not in name: assert np.allclose(ret.unit_iabs.jmax, expected['jmax']) else: warnings.warn('Skipping Jmax test for cases with numerical instability') # Check Iabs scaling iabs = ret.unit_iabs.scale_iabs(values['fapar_sc'], values['ppfd_sc']) # Find the expected values, extracting the combination from the request expected = values['rpmodel-c3-' + name + '-iabs'] assert np.allclose(iabs.gpp, expected['gpp']) assert np.allclose(iabs.vcmax, expected['vcmax']) assert np.allclose(iabs.vcmax25, expected['vcmax25']) assert np.allclose(iabs.rd, expected['rd']) assert np.allclose(iabs.gs, expected['gs']) if 'none-fkphio-off-sm-off' not in name: assert np.allclose(iabs.jmax, expected['jmax']) else: warnings.warn('Skipping Jmax test for cases with numerical instability')
def test_pmodel_class_c4(request, values, soilmstress, ftemp_kphio, variables): # Get the main vars kwargs = {k: values[v] for k, v in variables.items()} if soilmstress: soilmstress = pmodel.calc_soilmstress(values['soilm_sc'], values['meanalpha_sc']) else: soilmstress = None ret = pmodel.PModel(**kwargs, kphio=0.05, soilmstress=soilmstress, do_ftemp_kphio=ftemp_kphio, method_jmaxlim='none', # enforced in rpmodel. c4=True) # Find the expected values, extracting the combination from the request name = request.node.name name = name[(name.find('[') + 1):-1] expected = values['rpmodel-c4-' + name + '-unitiabs'] # Test values - two values calculated in main rpmodel function # so can only test here - ci and iwue assert np.allclose(ret.iwue, expected['iwue']) assert np.allclose(ret.optchi.ci, expected['ci']) # - and six values that are scaled by IABS - rpmodel enforces scaling # where PModel can do it post hoc from unit_iabs values, so two # rpmodel runs are used to test the unit values and scaled. unit_iabs = ret.unit_iabs.scale_iabs(1, 1) assert np.allclose(unit_iabs.lue, expected['lue']) assert np.allclose(unit_iabs.vcmax, expected['vcmax']) assert np.allclose(unit_iabs.vcmax25, expected['vcmax25']) assert np.allclose(unit_iabs.rd, expected['rd']) assert np.allclose(unit_iabs.jmax, expected['jmax']) assert np.allclose(unit_iabs.gs, expected['gs']) # Check Iabs scaling iabs = ret.unit_iabs.scale_iabs(values['fapar_sc'], values['ppfd_sc']) # Find the expected values, extracting the combination from the request expected = values['rpmodel-c4-' + name + '-iabs'] assert np.allclose(iabs.gpp, expected['gpp']) assert np.allclose(iabs.vcmax, expected['vcmax']) assert np.allclose(iabs.vcmax25, expected['vcmax25']) assert np.allclose(iabs.rd, expected['rd']) assert np.allclose(iabs.jmax, expected['jmax']) assert np.allclose(iabs.gs, expected['gs'])
def test_pmodel_class_c3(request, values, pmodelenv, soilmstress, ftemp_kphio, environ): if soilmstress: soilmstress = pmodel.calc_soilmstress(values['soilm_sc'], values['meanalpha_sc']) else: soilmstress = None ret = pmodel.PModel( pmodelenv[environ], kphio=0.05, soilmstress=soilmstress, do_ftemp_kphio=ftemp_kphio, method_jmaxlim='none', # enforced in rpmodel. c4=True) # Find the expected values, extracting the combination from the request name = request.node.name name = name[(name.find('[') + 1):-1] expected = values['rpmodel-c4-' + name + '-unitiabs'] # Test values - two values calculated in main rpmodel function # so can only test here - ci and iwue assert np.allclose(ret.iwue, expected['iwue']) assert np.allclose(ret.optchi.ci, expected['ci']) # - and six values that are scaled by IABS - rpmodel enforces scaling # where PModel can do it post hoc from unit_iabs values, so two # rpmodel runs are used to test the unit values and scaled. ret.estimate_productivity() # defaults of fapar=1, ppfd=1 assert np.allclose(ret.lue, expected['lue']) assert np.allclose(ret.vcmax, expected['vcmax']) assert np.allclose(ret.vcmax25, expected['vcmax25']) assert np.allclose(ret.rd, expected['rd']) assert np.allclose(ret.jmax, expected['jmax']) assert np.allclose(ret.gs, expected['gs']) # Check Iabs scaling ret.estimate_productivity(fapar=values['fapar_sc'], ppfd=values['ppfd_sc']) # Find the expected values, extracting the combination from the request expected = values['rpmodel-c4-' + name + '-iabs'] assert np.allclose(ret.gpp, expected['gpp']) assert np.allclose(ret.vcmax, expected['vcmax']) assert np.allclose(ret.vcmax25, expected['vcmax25']) assert np.allclose(ret.rd, expected['rd']) assert np.allclose(ret.jmax, expected['jmax']) assert np.allclose(ret.gs, expected['gs'])
def test_calc_lue_vcmax(request, values, soilmstress, ftemp_kphio, luevcmax_method, optchi, c4): # ftemp_kphio needs to know the original tc inputs to optchi - these have # all been synchronised so that anything with type 'mx' or 'ar' used the # tc_ar input if c4: oc_method = 'c4' pytest.skip( 'Not currently testing C4 outputs because of param in rpmodel') else: oc_method = 'prentice14' if not ftemp_kphio: ftemp_kphio = 1.0 elif optchi['kmm'] == 'kmm_sc': ftemp_kphio = pmodel.calc_ftemp_kphio(tc=values['tc_sc'], c4=c4) else: ftemp_kphio = pmodel.calc_ftemp_kphio(tc=values['tc_ar'], c4=c4) # Optimal Chi kwargs = {k: values[v] for k, v in optchi.items()} optchi = pmodel.CalcOptimalChi(**kwargs, method=oc_method) # Soilmstress if soilmstress['soilm'] is None: soilmstress = 1.0 else: soilmstress = pmodel.calc_soilmstress( soilm=values[soilmstress['soilm']], meanalpha=values[soilmstress['meanalpha']]) ret = pmodel.CalcLUEVcmax(optchi, kphio=0.05, ftemp_kphio=ftemp_kphio, soilmstress=soilmstress, method=luevcmax_method) # Find the expected values, extracting the combination from the request name = request.node.name name = name[(name.find('[') + 1):-1] expected = values['jmax-' + name] assert np.allclose(ret.lue, expected['lue']) assert np.allclose(ret.vcmax, expected['vcmax_unitiabs']) if luevcmax_method == 'smith19': assert np.allclose(ret.omega, expected['omega']) assert np.allclose(ret.omega_star, expected['omega_star'])
def test_calc_soilmstress(values, ctrl): with ctrl['cmng']: kwargs = {k: values[v] for k, v in ctrl['args'].items()} ret = pmodel.calc_soilmstress(**kwargs) assert np.allclose(ret, values[ctrl['out']])