def test_initial_data_processing(self): """ Test whether the background and scale are handled properly when creating an InvariantCalculator object """ length = len(self.data.x) self.assertEqual(length, len(self.data.y)) inv = invariant.InvariantCalculator(self.data) self.assertEqual(length, len(inv._data.x)) self.assertEqual(inv._data.x[0], self.data.x[0]) # Now the same thing with a background value bck = 0.1 inv = invariant.InvariantCalculator(self.data, background=bck) self.assertEqual(inv._background, bck) self.assertEqual(length, len(inv._data.x)) self.assertEqual(inv._data.y[0]+bck, self.data.y[0]) # Now the same thing with a scale value scale = 0.1 inv = invariant.InvariantCalculator(self.data, scale=scale) self.assertEqual(inv._scale, scale) self.assertEqual(length, len(inv._data.x)) self.assertAlmostEqual(inv._data.y[0]/scale, self.data.y[0],7)
def test_qstar_low_q_guinier(self): """ Test low-q extrapolation with a Guinier """ inv = invariant.InvariantCalculator(self.data) # Basic sanity check _qstar = inv.get_qstar() qstar, dqstar = inv.get_qstar_with_error() self.assertEqual(qstar, _qstar) # Low-Q Extrapolation # Check that the returned invariant is what we expect given # the result we got without extrapolation inv.set_extrapolation('low', npts=10, function='guinier') qs_extr, dqs_extr = inv.get_qstar_with_error('low') delta_qs_extr, delta_dqs_extr = inv.get_qstar_low() self.assertEqual(qs_extr, _qstar+delta_qs_extr) self.assertEqual(dqs_extr, math.sqrt(dqstar*dqstar + delta_dqs_extr*delta_dqs_extr)) # We don't expect the extrapolated invariant to be very far from the # result without extrapolation. Let's test for a result within 10%. self.assertTrue(math.fabs(qs_extr-qstar)/qstar<0.1) # Check that the two results are consistent within errors # Note that the error on the extrapolated value takes into account # a systematic error for the fact that we may not know the shape of I(q) at low Q. self.assertTrue(math.fabs(qs_extr-qstar)<dqs_extr)
def test_qstar_high_q(self): """ Test high-q extrapolation """ inv = invariant.InvariantCalculator(self.data) # Basic sanity check _qstar = inv.get_qstar() qstar, dqstar = inv.get_qstar_with_error() self.assertEqual(qstar, _qstar) # High-Q Extrapolation # Check that the returned invariant is what we expect given # the result we got without extrapolation inv.set_extrapolation('high', npts=20, function='power_law') qs_extr, dqs_extr = inv.get_qstar_with_error('high') delta_qs_extr, delta_dqs_extr = inv.get_qstar_high() # From previous analysis using SasView, we expect an exponent of about 3 self.assertTrue(math.fabs(inv._high_extrapolation_function.power-3)<0.1) self.assertEqual(qs_extr, _qstar+delta_qs_extr) self.assertAlmostEqual(dqs_extr, math.sqrt(dqstar*dqstar + delta_dqs_extr*delta_dqs_extr), 10) # We don't expect the extrapolated invariant to be very far from the # result without extrapolation. Let's test for a result within 10%. #TODO: verify whether this test really makes sense #self.assertTrue(math.fabs(qs_extr-qstar)/qstar<0.1) # Check that the two results are consistent within errors self.assertTrue(math.fabs(qs_extr-qstar)<dqs_extr)
def test_use_case_6(self): """ Invariant with high-Q extrapolation """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the high-Q range inv.set_extrapolation(range='low', npts=10, function='power_law', power=4) # The version of the call without error # The function parameter defaults to None, then is picked to be 'power_law' for extrapolation='high' qstar = inv.get_qstar(extrapolation='low') # The version of the call with error qstar, qstar_err = inv.get_qstar_with_error(extrapolation='low') # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) # Test results self.assertAlmostEquals(qstar, 7.49e-5, 2) self.assertAlmostEquals(v, 0.005952674, 3) self.assertAlmostEquals(s, 941.7452, 3)
def test_qstar_high_q(self): """ Test high-q extrapolation """ inv = invariant.InvariantCalculator(self.data) # Basic sanity check _qstar = inv.get_qstar() qstar, dqstar = inv.get_qstar_with_error() self.assertEqual(qstar, _qstar) # High-Q Extrapolation # Check that the returned invariant is what we expect given # the result we got without extrapolation inv.set_extrapolation('high', npts=75, function='power_law') qs_extr, dqs_extr = inv.get_qstar_with_error('high') delta_qs_extr, delta_dqs_extr = inv.get_qstar_high() # In principle the slope should be -4. However due to the oscillations # and finite number of points we need quite a lot of points to ensure # that the fit averages close to 4. SasView estimates 3.92 at the # moment self.assertTrue(math.fabs(inv._high_extrapolation_function.power-4)<0.1) self.assertEqual(qs_extr, _qstar+delta_qs_extr) self.assertAlmostEqual(dqs_extr, math.sqrt(dqstar*dqstar \ + delta_dqs_extr*delta_dqs_extr), 10)
def test_use_case_2(self): """ Test the Invariant with the low-Q Guinier extrapolation. This should now capture 98.5% of the invariant so in principle the calculation should give a value that is 1.5% below the theoretical value. This should be within tolerance so leave the invariant test value at the true theoretical value here. """ # Create an invariant object with the background set to zero inv = invariant.InvariantCalculator(data=self.data_q_smear, background=0) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='low', npts=10, function='guinier') # again using calls to both for reasons described in previous test # classes above. qstar1 = inv.get_qstar(extrapolation='low') qstar, qstar_err = inv.get_qstar_with_error(extrapolation='low') # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.2e-6) s, ds = inv.get_surface_with_error(contrast=2.2e-6, porod_const=1.825e-8) # Test results self.assertEqual(qstar1, qstar) self.assertAlmostEqual(qstar, 9.458239e-5, delta=1.5e-6) self.assertAlmostEqual(v, 0.01, delta=15e-4) self.assertAlmostEqual(s, 6.000e-6, 7)
def test_use_case_4(self): """ Test the Invariant with both the low Q Guinier and the high-Q -4 power law extrapolations. This should now capture all the invariant so we now again give the true theoretical invariant as the test value to compare agains. """ # Create an invariant object with the background set to zero inv = invariant.InvariantCalculator(data=self.data_q_smear, background=0) # Set the extrapolation parameters for the low- and high-Q ranges inv.set_extrapolation(range='low', npts=10, function='guinier') inv.set_extrapolation(range='high', npts=10, function='power_law', power=4) # again using calls to both for reasons described in previous test # classes above. qstar1 = inv.get_qstar(extrapolation='low') qstar, qstar_err = inv.get_qstar_with_error(extrapolation='low') # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.2e-6) s, ds = inv.get_surface_with_error(contrast=2.2e-6, porod_const=1.825e-8) # Test results self.assertEqual(qstar1, qstar) self.assertAlmostEqual(qstar, 9.458239e-5, delta=1.5e-6) self.assertAlmostEqual(v, 0.01, delta=15e-4) self.assertAlmostEqual(s, 6.000e-6, 7)
def test_use_case_1(self): """ Test the Invariant without extrapolation. Because the object is so large and in this case I is only multiplied by q rather than q^2, a significant part of the invariant (~6.5%)is not captured with most of that (~5%) being in the low Q region. Thus the valuefor the invariant here is being adjusted down by 6.5% As seen when both extrapolations are included the integration seems to be computing a percent or two high. """ # Create an invariant object with background of zero as that is how the # data was created. A different background could cause negative # intensities. Leave scale as defaults. inv = invariant.InvariantCalculator(data=self.data_q_smear, background=0) # again using calls to both for reasons described in previous test # classes above. qstar1 = inv.get_qstar() qstar, qstar_err = inv.get_qstar_with_error() # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.2e-6) s, ds = inv.get_surface_with_error(contrast=2.2e-6, porod_const=1.825e-8) # Test results self.assertEqual(qstar1, qstar) self.assertAlmostEqual(qstar, 8.8434e-5, delta=1.5e-6) self.assertAlmostEqual(v, 0.00935, delta=1.5e-4) self.assertAlmostEqual(s, 6.000e-6, 7)
def test_low_q(self): """ Invariant with low-Q extrapolation """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='low', npts=20, function='guinier') self.assertEqual(inv._low_extrapolation_npts, 20) self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier) # Data boundaries for fiiting qmin = inv._data.x[0] qmax = inv._data.x[inv._low_extrapolation_npts - 1] # Extrapolate the low-Q data inv._fit(model=inv._low_extrapolation_function, qmin=qmin, qmax=qmax, power=inv._low_extrapolation_power) self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6) self.assertAlmostEqual(self.rg, inv._low_extrapolation_function.radius, 6)
def test_low_data(self): """ Invariant with low-Q extrapolation with slit smear """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='low', npts=self.npts, function='guinier') self.assertEqual(inv._low_extrapolation_npts, self.npts) self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier) # Data boundaries for fiiting qmin = inv._data.x[0] qmax = inv._data.x[inv._low_extrapolation_npts - 1] # Extrapolate the low-Q data inv._fit(model=inv._low_extrapolation_function, qmin=qmin, qmax=qmax, power=inv._low_extrapolation_power) qstar = inv.get_qstar(extrapolation='low') #Compution the y 's coming out of the invariant when computing extrapolated #low data . expect the fit engine to have been already called and the guinier # to have the radius and the scale fitted data_in_range = inv.get_extra_data_low(q_start=self.data.x[0], npts = inv._low_extrapolation_npts) test_y = data_in_range.y self.assertTrue(len(test_y) == len(self.data.y[:inv._low_extrapolation_npts])) for i in range(inv._low_extrapolation_npts): value = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i] self.assertTrue(value < 0.001)
def test_use_case_1(self): """ Invariant without extrapolation """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # We have to be able to tell the InvariantCalculator whether we want the # extrapolation or not. By default, when the user doesn't specify, we # should compute Q* without extrapolation. That's what should be done # in __init__. # We call get_qstar() with no argument, which signifies that we do NOT # want extrapolation. qstar = inv.get_qstar() # The volume fraction and surface use Q*. That means that the following # methods should check that Q* has been computed. If not, it should # compute it by calling get_qstare(), leaving the parameters as default. v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) # Test results self.assertAlmostEquals(qstar, 7.48959e-5, 2) self.assertAlmostEquals(v, 0.005644689, 4) self.assertAlmostEquals(s, 941.7452, 3)
def test_low_q(self): """ Invariant with low-Q extrapolation NOTE: as noted in the class docs, this should probalby be removed. But until we remove the option for low Q power law extrapolation will leave this. """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='low', npts=20, function='power_law') self.assertEqual(inv._low_extrapolation_npts, 20) self.assertEqual(inv._low_extrapolation_function.__class__, invariant.PowerLaw) # Data boundaries for fitting qmin = inv._data.x[0] qmax = inv._data.x[inv._low_extrapolation_npts - 1] # Extrapolate the low-Q data inv._fit(model=inv._low_extrapolation_function, qmin=qmin, qmax=qmax, power=inv._low_extrapolation_power) self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6) self.assertAlmostEqual(self.m, inv._low_extrapolation_function.power, 6)
def test_low_q(self): """ Invariant with low-Q extrapolation with no slit smear """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='low', npts=10, function='guinier') self.assertEqual(inv._low_extrapolation_npts, 10) self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier) # Data boundaries for fiiting qmin = inv._data.x[0] qmax = inv._data.x[inv._low_extrapolation_npts - 1] # Extrapolate the low-Q data inv._fit(model=inv._low_extrapolation_function, qmin=qmin, qmax=qmax, power=inv._low_extrapolation_power) self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6) self.assertAlmostEqual(self.rg, inv._low_extrapolation_function.radius, 6) qstar = inv.get_qstar(extrapolation='low') test_y = inv._low_extrapolation_function.evaluate_model(x=self.data.x) for i in range(len(self.data.x)): value = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i] self.assertTrue(value < 0.001)
def test_use_case_3(self): """ Invariant with low-Q extrapolation """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the low-Q range # The npts parameter should have a good default. # The range parameter should be 'high' or 'low' # The function parameter should default to None. If it is None, # the method should pick a good default (Guinier at low-Q and 1/q^4 at high-Q). # The method should also check for consistency of the extrapolation and function # parameters. For instance, you might not want to allow 'high' and 'guinier'. # The power parameter (not shown below) should default to 4. inv.set_extrapolation(range='low', npts=10, function='guinier') # The version of the call without error # At this point, we could still compute Q* without extrapolation by calling # get_qstar with arguments, or with extrapolation=None. qstar = inv.get_qstar(extrapolation='low') # The version of the call with error qstar, qstar_err = inv.get_qstar_with_error(extrapolation='low') # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) # Test results self.assertAlmostEquals(qstar, 7.49e-5, 1) self.assertAlmostEquals(v, 0.005648401, 4) self.assertAlmostEquals(s , 941.7452, 3)
def test_high_data(self): """ Invariant with low-Q extrapolation with slit smear """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='high', npts=self.npts, function='power_law') self.assertEqual(inv._high_extrapolation_npts, self.npts) self.assertEqual(inv._high_extrapolation_function.__class__, invariant.PowerLaw) # Data boundaries for fiiting xlen = len(self.data.x) start = xlen - inv._high_extrapolation_npts qmin = inv._data.x[start] qmax = inv._data.x[xlen-1] # Extrapolate the high-Q data inv._fit(model=inv._high_extrapolation_function, qmin=qmin, qmax=qmax, power=inv._high_extrapolation_power) qstar = inv.get_qstar(extrapolation='high') data_in_range= inv.get_extra_data_high(q_end = max(self.data.x), npts = inv._high_extrapolation_npts) test_y = data_in_range.y self.assertTrue(len(test_y) == len(self.data.y[start:])) temp = self.data.y[start:] for i in range(len(self.data.x[start:])): value = math.fabs(test_y[i]- temp[i])/temp[i] self.assertTrue(value < 0.001)
def test_use_case_3(self): """ Test the Invariant with the high-Q -4 power law extrapolation. This should still only capture 95% of the true invariant so i principle the calculation should give a value that is 5% lower than the true theoretical value. Thus here again we adjust the test value for the invariant down, this time by 5%. """ # Create an invariant object with the background set to zero inv = invariant.InvariantCalculator(data=self.data_q_smear, background=0) # Set the extrapolation parameters for the high-Q range inv.set_extrapolation(range='high', npts=10, function='power_law', power=4) # again using calls to both for reasons described in previous test # classes above. qstar1 = inv.get_qstar(extrapolation='high') qstar, qstar_err = inv.get_qstar_with_error(extrapolation='high') # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.2e-6) s, ds = inv.get_surface_with_error(contrast=2.2e-6, porod_const=1.825e-8) # Test results self.assertEqual(qstar1, qstar) self.assertAlmostEqual(qstar, 8.9853e-5, delta=1.5e-6) self.assertAlmostEqual(v, 0.0095, delta=1.5e-4) self.assertAlmostEqual(s, 6.000e-6, 7)
def test_bad_parameter_name(self): """ The set_extrapolation method checks that the name of the extrapolation function and the name of the q-range to extrapolate (high/low) is recognized. """ inv = invariant.InvariantCalculator(self.data) self.assertRaises(ValueError, inv.set_extrapolation, 'low', npts=4, function='not_a_name') self.assertRaises(ValueError, inv.set_extrapolation, 'not_a_range', npts=4, function='guinier') self.assertRaises(ValueError, inv.set_extrapolation, 'high', npts=4, function='guinier')
def test_use_case_1(self): """ Invariant without extrapolation """ inv = invariant.InvariantCalculator(data=self.data_q_smear) qstar = inv.get_qstar() v = inv.get_volume_fraction(contrast=2.6e-6) s = inv.get_surface(contrast=2.6e-6, porod_const=2) # Test results self.assertAlmostEquals(qstar, 1.361677e-3, 4) self.assertAlmostEquals(v, 0.115352622, 2) self.assertAlmostEquals(s, 941.7452, 3)
def test_qstar_low_q_power_law(self): """ Test low-q extrapolation with a power law """ inv = invariant.InvariantCalculator(self.data) # Basic sanity check _qstar = inv.get_qstar() qstar, dqstar = inv.get_qstar_with_error() self.assertEqual(qstar, _qstar) # Low-Q Extrapolation # Check that the returned invariant is what we expect given inv.set_extrapolation('low', npts=10, function='power_law') qs_extr, dqs_extr = inv.get_qstar_with_error('low') delta_qs_extr, delta_dqs_extr = inv.get_qstar_low() # A fit using SasView gives 0.0655 for the value of the exponent self.assertAlmostEqual(inv._low_extrapolation_function.power, 0.0655, 3) if False: npts = len(inv._data.x) - 1 import matplotlib.pyplot as plt plt.loglog(inv._data.x[:npts], inv._data.y[:npts], 'o', label='Original data', markersize=10) plt.loglog(inv._data.x[:npts], inv._low_extrapolation_function.evaluate_model( inv._data.x[:npts]), 'r', label='Fitted line') plt.legend() plt.show() self.assertEqual(qs_extr, _qstar + delta_qs_extr) self.assertAlmostEqual( dqs_extr, math.sqrt(dqstar * dqstar + delta_dqs_extr * delta_dqs_extr), 15) # We don't expect the extrapolated invariant to be very far from the # result without extrapolation. Let's test for a result within 10%. self.assertTrue(math.fabs(qs_extr - qstar) / qstar < 0.1) # Check that the two results are consistent within errors # Note that the error on the extrapolated value takes into account # a systematic error for the fact that we may not know the shape of I(q) at low Q. self.assertTrue(math.fabs(qs_extr - qstar) < dqs_extr)
def test_use_case_4(self): """ Invariant with high-Q extrapolation """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data_q_smear) # Set the extrapolation parameters for the high-Q range inv.set_extrapolation(range='high', npts=10, function='power_law', power=4) # The version of the call without error qstar = inv.get_qstar(extrapolation='high') # The version of the call with error qstar, qstar_err = inv.get_qstar_with_error(extrapolation='high') # Test results self.assertAlmostEqual(qstar, 0.0045773,2)
def test_error_treatment(self): x = np.asarray(np.asarray([0,1,2,3])) y = np.asarray(np.asarray([1,1,1,1])) # These are all the values of the dy array that would cause # us to set all dy values to 1.0 at __init__ time. dy_list = [ [], None, [0,0,0,0] ] for dy in dy_list: data = Data1D(x=x, y=y, dy=dy) inv = invariant.InvariantCalculator(data) self.assertEqual(len(inv._data.x), len(inv._data.dy)) self.assertEqual(len(inv._data.dy), 4) for i in range(4): self.assertEqual(inv._data.dy[i],1)
def test_use_case_2(self): """ Tes the Invariant with the low-Q Guinier extrapolation """ # Create an invariant object with background of zero as that is how the # data was created. A different background could cause negative # intensities. Leave scale as defaults. inv = invariant.InvariantCalculator(data=self.data, background=0) # Now we do want to use the extrapoloation so first we need to set # the extrapolation parameters, in thsi case for the low-Q range # The npts parameter should have a good default. # The range parameter should be 'high' or 'low' # The function parameter should default to None. If it is None, # the method should pick a good default # (Guinier at low-Q and 1/q^4 at high-Q). # The method should also check for consistency of the extrapolation # and function parameters. For instance, you might not want to allow # 'high' and 'guinier'. # The power parameter (not shown below) should default to 4. inv.set_extrapolation(range='low', npts=10, function='guinier') # The version of the call without error again checks that the function # returns the same value as it calculates and passes to the verion of # the call with uncertainties. # # Note that at this point, we could still compute Q* without # extrapolation by calling get_qstar with no arguments, or with # extrapolation=None. # But of course we want to test the low Q Guinier extrapolation so... qstar1 = inv.get_qstar(extrapolation='low') # And again, using the version of the call which also retruns # the uncertainties. qstar, qstar_err = inv.get_qstar_with_error(extrapolation='low') # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.2e-6) s, ds = inv.get_surface_with_error(contrast=2.2e-6, porod_const=1.825e-7) # Test results self.assertEqual(qstar1, qstar) self.assertAlmostEqual(qstar, 1.088e-4, delta=1e-6) self.assertAlmostEqual(v, 0.01150, delta=1e-4) self.assertAlmostEqual(s, 6.000e-5, 7)
def test_use_case_2(self): """ Invariant without extrapolation. Invariant, volume fraction and surface are given with errors. """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data_q_smear) # Get the invariant with errors qstar, qstar_err = inv.get_qstar_with_error() # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) # Test results self.assertAlmostEquals(qstar, 1.361677e-3, 4) self.assertAlmostEquals(v, 0.115352622, 2) self.assertAlmostEquals(s, 941.7452, 3)
def test_use_case_5(self): """ Invariant with both high- and low-Q extrapolation """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data_q_smear) # Set the extrapolation parameters for the low- and high-Q ranges inv.set_extrapolation(range='low', npts=10, function='guinier') inv.set_extrapolation(range='high', npts=10, function='power_law', power=4) # The version of the call without error # The function parameter defaults to None, then is picked to be # 'power_law' for extrapolation='high' qstar = inv.get_qstar(extrapolation='both') # The version of the call with error qstar, qstar_err = inv.get_qstar_with_error(extrapolation='both') # Test results self.assertAlmostEqual(qstar, 0.00460319,3)
def test_use_case_2(self): """ Invariant without extrapolation. Invariant, volume fraction and surface are given with errors. """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Get the invariant with errors qstar, qstar_err = inv.get_qstar_with_error() # The volume fraction and surface use Q*. That means that the following # methods should check that Q* has been computed. If not, it should # compute it by calling get_qstare(), leaving the parameters as default. v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) # Test results self.assertAlmostEquals(qstar, 7.48959e-5, 2) self.assertAlmostEquals(v, 0.005644689, 1) self.assertAlmostEquals(s, 941.7452, 3)
def test_use_case_3(self): """ Invariant with low-Q extrapolation """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data_q_smear) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='low', npts=20, function='guinier') # The version of the call without error qstar = inv.get_qstar(extrapolation='low') # The version of the call with error qstar, qstar_err = inv.get_qstar_with_error(extrapolation='low') # Get the volume fraction and surface v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) # Test results self.assertAlmostEquals(qstar, 0.00138756, 2) self.assertAlmostEquals(v, 0.117226896, 2) self.assertAlmostEquals(s, 941.7452, 3)
def test_qstar_low_q_guinier(self): """ Test low-q extrapolation with a Guinier """ inv = invariant.InvariantCalculator(self.data) # Basic sanity check _qstar = inv.get_qstar() qstar, dqstar = inv.get_qstar_with_error() self.assertEqual(qstar, _qstar) # Low-Q Extrapolation # Check that the returned invariant is what we expect given # the result we got without extrapolation inv.set_extrapolation('low', npts=10, function='guinier') qs_extr, dqs_extr = inv.get_qstar_with_error('low') delta_qs_extr, delta_dqs_extr = inv.get_qstar_low() self.assertEqual(qs_extr, _qstar+delta_qs_extr) self.assertEqual(dqs_extr, math.sqrt(dqstar*dqstar + delta_dqs_extr*delta_dqs_extr))
def test_high_q(self): """ Invariant with high-Q extrapolation with slit smear TODO:: As of 3/23/2020 by PDB - this data is NOT smeared as far as I can see. On the other hand it is the only high q extrapolation test? Need to double check then rewrite doc strings accordingly. """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='high', npts=self.npts, function='power_law') self.assertEqual(inv._high_extrapolation_npts, self.npts) self.assertEqual(inv._high_extrapolation_function.__class__, invariant.PowerLaw) # Data boundaries for fiiting xlen = len(self.data.x) start = xlen - inv._high_extrapolation_npts qmin = inv._data.x[start] qmax = inv._data.x[xlen-1] # Extrapolate the high-Q data inv._fit(model=inv._high_extrapolation_function, qmin=qmin, qmax=qmax, power=inv._high_extrapolation_power) qstar = inv.get_qstar(extrapolation='high') test_y = inv._high_extrapolation_function.evaluate_model(x=self.data.x[start: ]) self.assertTrue(len(test_y) == len(self.data.y[start:])) for i in range(len(self.data.x[start:])): value = math.fabs(test_y[i]-self.data.y[start+i])/self.data.y[start+i] self.assertTrue(value < 0.001)
def test_low_data(self): """ Invariant with low-Q extrapolation with slit smear TODO:: on 3/23/2020 PDB says: a) there is no slit smear data here and b) this seems to be the exactly the same tests as test_low_q and of the whole class TestDataExtraLow which iteself is a superset of the class TestGunierExtrapolation? """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data) # Set the extrapolation parameters for the low-Q range inv.set_extrapolation(range='low', npts=self.npts, function='guinier') self.assertEqual(inv._low_extrapolation_npts, self.npts) self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier) # Data boundaries for fiiting qmin = inv._data.x[0] qmax = inv._data.x[inv._low_extrapolation_npts - 1] # Extrapolate the low-Q data inv._fit(model=inv._low_extrapolation_function, qmin=qmin, qmax=qmax, power=inv._low_extrapolation_power) qstar = inv.get_qstar(extrapolation='low') #Computing the ys coming out of the invariant when computing # extrapolated low data . expect the fit engine to have been already # called and the guinier to have the radius and the scale fitted data_in_range = inv.get_extra_data_low(q_start=self.data.x[0], npts = inv._low_extrapolation_npts) test_y = data_in_range.y self.assertTrue(len(test_y) == len(self.data.y[:inv._low_extrapolation_npts])) for i in range(inv._low_extrapolation_npts): value = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i] self.assertTrue(value < 0.001)
def test_use_case_5(self): """ Invariant with both high- and low-Q extrapolation """ # Create invariant object. Background and scale left as defaults. inv = invariant.InvariantCalculator(data=self.data_q_smear) # Set the extrapolation parameters for the low- and high-Q ranges inv.set_extrapolation(range='low', npts=10, function='guinier') inv.set_extrapolation(range='high', npts=10, function='power_law', power=4) # The version of the call without error # The function parameter defaults to None, then is picked to be 'power_law' for extrapolation='high' qstar = inv.get_qstar(extrapolation='both') # The version of the call with error qstar, qstar_err = inv.get_qstar_with_error(extrapolation='both') # Get the volume fraction and surface # WHY SHOULD THIS FAIL? #self.assertRaises(RuntimeError, inv.get_volume_fraction_with_error, 2.6e-6) #self.assertRaises(RuntimeError, inv.get_surface_with_error, 2.6e-6, 2) # Test results self.assertAlmostEquals(qstar, 0.00460319,3)