コード例 #1
0
def f_model_example():
  """ This example illustrates the use of the f_model class"""

  # make up some structure factors
  random_structure = rs.xray_structure(
    sgtbx.space_group_info( 'P1' ),
    elements=['C']*310,
    n_scatterers=310)

  # here f_atoms, f_mask and f_part are all the same
  # doens't make sense of course
  sfs = random_structure.structure_factors( False, 3.5,  ).f_calc()
  f_model_structure_factors =  xray.f_model_core_data( hkl = sfs.indices(),
                                             f_atoms= sfs.data(),
                                             f_mask = sfs.data(),
                                             unit_cell = sfs.unit_cell(),
                                             k_overall=1.0,
                                             u_star=(0,0,0,0,0,0),
                                             k_sol=1.0,
                                             u_sol=1.0,
                                             f_part=None,
                                             k_part=0,
                                             u_part=0 )

  #Resetting model parameters
  #
  # over all scale parameters; scale and aniso Ustar
  f_model_structure_factors.renew_overall_scale_parameters(
    3.0,(0,0,0,0,0,0) )
  # bulk solvent scale parameters; scale and B
  f_model_structure_factors.renew_bulk_solvent_scale_parameters(0.55,50.0)
  # partial structure scale parameters; scale and B
  f_model_structure_factors.renew_partial_structure_scale_parameters(0.05,25.0)

  # is is also possible to reset the values term by term ratrher then grouped
  f_model_structure_factors.ksol( 1.0 )
  f_model_structure_factors.usol( 3.0 )
  f_model_structure_factors.kpart( 1.0 )
  f_model_structure_factors.upart( 3.0 )
  f_model_structure_factors.koverall( 1.0 )
  f_model_structure_factors.ustar( (0,0,0,0,0,0) )
  # the cached arrays of various scale factor as updated automatically.

  # Obtaining the current parameters
  ksol = f_model_structure_factors.ksol()
  bsol = f_model_structure_factors.usol()
  kpart = f_model_structure_factors.kpart()
  bpart = f_model_structure_factors.upart()
  koverall = f_model_structure_factors.koverall()
  ustar = f_model_structure_factors.ustar()

  # Derivatives
  #
  #
  #derivates can be obtained accumalated over the full dataset
  # or on a struct term by term bases
  #what is needed in any case are one of the following arrays or floats
  # - d(target)/d(|F_model|)
  # - d(target)/d(Re[F_model]), d(target)/d(Im[F_model])
  #
  # which derivates are computed, is controlled by an array of gradient flags:
  # the order is (koverall, ustar, ksol, bsol, kpart, bpart )
  #
  gradient_flags = flex.bool([True,True,
                              True,True,
                              True,True])
  #
  # Use this function call is your target function returns
  # d(target)/d(|Fmodel|)
  dt_dabsfmodel = flex.double( sfs.data().size(), 1 )
  dtdall = f_model_structure_factors.d_target_d_all(
    dt_dabsfmodel,gradient_flags )

  # Use this function call is your target function returns
  # d(target)/d(Re[Fmodel]), d(target)/d(Im[Fmodel])
  dtda = dt_dabsfmodel
  dtdb = dt_dabsfmodel

  dtdall = f_model_structure_factors.d_target_d_all(
    dtda, dtdb, gradient_flags)
  # if desired (likely in c++, not in python) you can do it term by term.
  hkl_no=123
  dtdsingle = f_model_structure_factors.d_target_d_all(
    dtda[hkl_no], dtdb[hkl_no], hkl_no, gradient_flags)

  # the resulting gradients are delivered as a
  # 'f_model_derivative_holder'
  # it has methods both to set as well as to get items.
  #
  # getting the values
  tmp = dtdsingle.koverall()
  tmp = dtdsingle.ustar()
  tmp = dtdsingle.ksol()
  tmp = dtdsingle.usol()
  tmp = dtdsingle.kpart()
  tmp = dtdsingle.upart()
  #
  # if desired, you can set values as well
  dtdsingle.koverall(1)
  dtdsingle.ustar(  (1,1,1,1,1,1)  )
  dtdsingle.ksol(1)
  dtdsingle.usol(1)
  dtdsingle.kpart(1)
  dtdsingle.upart(1)



  #if desired, a selection can be made on the f_model object.
  #currently, only an integer selection is supported
  new_f_model_object = f_model_structure_factors.select( flex.int([1,2,3]) )
  assert  new_f_model_object.f_model().size()==3
コード例 #2
0
ファイル: tst_f_model.py プロジェクト: cctbx/cctbx-playground
def tst_f_model(this_hkl=123):
  tmp = rs.xray_structure(sgtbx.space_group_info( 'P1' ),
                          elements=['C']*310,
                          n_scatterers=310)

  sfs = tmp.structure_factors( False, 3.5,  ).f_calc()
  f_mod = xray.f_model_core_data( hkl = sfs.indices(),
                        f_atoms= sfs.data(),
                        f_mask = sfs.data(),
                        unit_cell = sfs.unit_cell(),
                        k_overall=1.0,
                        u_star=(0,0,0,0,0,0),
                        k_sol=1.0,
                        u_sol=1.0,
                        f_part=sfs.data(),
                        k_part=1.0,
                        u_part=1.0 )

  data1 = sfs.data()[this_hkl]
  hkl1 =  sfs.indices()[this_hkl]

  fbulk = f_mod.f_bulk()[this_hkl]
  fatoms = f_mod.f_atoms()[this_hkl]
  fpart = f_mod.f_part()[this_hkl]
  fmod = f_mod.f_model()[this_hkl]
  # we have unit scale now
  assert approx_equal( fmod, fbulk+fatoms+fpart )
  # get derivatives please
  #
  # make a mock target function: T=A^2 + B^2
  # dT/dF=2F
  # dT/dA=2A
  # dT/dB=2B
  f_model_data_complex = f_mod.f_model()
  fm = flex.double()
  a = flex.double()
  b = flex.double()

  for cmplx in f_model_data_complex:
    tmp_a=cmplx.real
    tmp_b=cmplx.imag
    fm.append( math.sqrt(tmp_a*tmp_a + tmp_b*tmp_b) )
    a.append( tmp_a )
    b.append( tmp_b )

  dtdf = 2.0*fm
  dtda = 2.0*a
  dtdb = 2.0*b

  gradient_flags=flex.bool([True,True,
                            True,True,
                            True,True])

  grads_f = f_mod.d_target_d_all(dtdf,gradient_flags)
  grads_ab = f_mod.d_target_d_all(dtda, dtdb,gradient_flags)
  compare_all(grads_ab,grads_f)

  f_mod = xray.f_model_core_data( hkl = sfs.indices(),
                        f_atoms= sfs.data(),
                        f_mask = sfs.data()*0.0,
                        unit_cell = sfs.unit_cell(),
                        k_overall=1.0,
                        u_star=(0,0,0,0,0,0),
                        k_sol=0.0,
                        u_sol=0.0,
                        f_part=sfs.data()*0.0,
                        k_part=0.0,
                        u_part=0.0 )
  f_mod.refresh()
  grad_123 = f_mod.d_target_d_all(0,1,this_hkl, gradient_flags)
  assert approx_equal( grad_123.koverall(),
                       f_mod.f_model()[this_hkl].imag/f_mod.koverall() )
  tps=19.7392088 # 2 pi^2
  h=hkl1[0]
  k=hkl1[1]
  l=hkl1[2]
  assert approx_equal( -2*tps*h*h*f_mod.f_model()[this_hkl].imag,
                       grad_123.ustar()[0] )
  assert approx_equal( -2*tps*k*k*f_mod.f_model()[this_hkl].imag,
                       grad_123.ustar()[1] )
  assert approx_equal( -2*tps*l*l*f_mod.f_model()[this_hkl].imag,
                       grad_123.ustar()[2] )
  assert approx_equal( -4*tps*h*k*f_mod.f_model()[this_hkl].imag,
                       grad_123.ustar()[3] )
  assert approx_equal( -4*tps*h*l*f_mod.f_model()[this_hkl].imag,
                       grad_123.ustar()[4] )
  assert approx_equal( -4*tps*k*l*f_mod.f_model()[this_hkl].imag,
                       grad_123.ustar()[5] )





  grad_123 = f_mod.d_target_d_all(1,0,this_hkl, gradient_flags)
  assert approx_equal( grad_123.koverall(),
                       f_mod.f_model()[this_hkl].real/f_mod.koverall() )
  tps=19.7392088
  h=hkl1[0]
  k=hkl1[1]
  l=hkl1[2]
  assert approx_equal( -2*tps*h*h*f_mod.f_model()[this_hkl].real,
                       grad_123.ustar()[0] )
  assert approx_equal( -2*tps*k*k*f_mod.f_model()[this_hkl].real,
                       grad_123.ustar()[1] )
  assert approx_equal( -2*tps*l*l*f_mod.f_model()[this_hkl].real,
                       grad_123.ustar()[2] )
  assert approx_equal( -4*tps*h*k*f_mod.f_model()[this_hkl].real,
                       grad_123.ustar()[3] )
  assert approx_equal( -4*tps*h*l*f_mod.f_model()[this_hkl].real,
                       grad_123.ustar()[4] )
  assert approx_equal( -4*tps*k*l*f_mod.f_model()[this_hkl].real,
                       grad_123.ustar()[5] )


  oldfm = xray.f_model_core_data( hkl = sfs.indices(),
                        f_atoms= sfs.data(),
                        f_mask = sfs.data()*1.0,
                        unit_cell = sfs.unit_cell(),
                        k_overall=1.0,
                        u_star=(0,0,0,0,0,0),
                        k_sol=1.0,
                        u_sol=1.0,
                        f_part=sfs.data()*1.0,
                        k_part=1.0,
                        u_part=1.0 )
  h=0.0001


  newfm = xray.f_model_core_data( hkl = sfs.indices(),
                        f_atoms= sfs.data(),
                        f_mask = sfs.data()*1.0,
                        unit_cell = sfs.unit_cell(),
                        k_overall=1.0,
                        u_star=(0,0,0,0,0,0),
                        k_sol=1.0,
                        u_sol=1.0,
                        f_part=sfs.data()*1.0,
                        k_part=1.0,
                        u_part=1.0 )


  newfm.renew_overall_scale_parameters(1.0+h, (0,0,0,0,0,0))
  newfm.refresh()

  tmp = oldfm.d_target_d_all(1,0,this_hkl,gradient_flags).koverall()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).real
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_overall_scale_parameters(1, (0,0,0,0,0,0))

  newfm.renew_bulk_solvent_scale_parameters(1+h,1.0)
  tmp = oldfm.d_target_d_all(1,0,this_hkl,gradient_flags).ksol()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).real
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_bulk_solvent_scale_parameters(1,1.0)

  newfm.renew_bulk_solvent_scale_parameters(1.0,1.0+h)
  tmp = oldfm.d_target_d_all(1,0,this_hkl,gradient_flags).usol()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).real
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_bulk_solvent_scale_parameters(1.0,1.0)

  newfm.renew_bulk_solvent_scale_parameters(1+h,1.0)
  tmp = oldfm.d_target_d_all(0,1,this_hkl,gradient_flags).ksol()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).imag
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_bulk_solvent_scale_parameters(1,1.0)

  newfm.renew_bulk_solvent_scale_parameters(1.0,1.0+h)
  tmp = oldfm.d_target_d_all(0,1,this_hkl,gradient_flags).usol()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).imag
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_bulk_solvent_scale_parameters(1.0,1.0)


  newfm.renew_partial_structure_scale_parameters(1+h,1.0)
  tmp = oldfm.d_target_d_all(1,0,this_hkl,gradient_flags).kpart()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).real
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_bulk_solvent_scale_parameters(1,1.0)

  newfm.renew_partial_structure_scale_parameters(1.0,1.0+h)
  tmp = oldfm.d_target_d_all(1,0,this_hkl,gradient_flags).upart()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).real
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_bulk_solvent_scale_parameters(1.0,1.0)

  newfm.renew_partial_structure_scale_parameters(1+h,1.0)
  tmp = oldfm.d_target_d_all(0,1,this_hkl,gradient_flags).kpart()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).imag
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_bulk_solvent_scale_parameters(1,1.0)

  newfm.renew_partial_structure_scale_parameters(1.0,1.0+h)
  tmp = oldfm.d_target_d_all(0,1,this_hkl,gradient_flags).upart()
  tmp_d = ((oldfm.f_model()[this_hkl]-newfm.f_model()[this_hkl])/(-h)).imag
  assert approx_equal( tmp,tmp_d,eps=1e-2 )
  newfm.renew_bulk_solvent_scale_parameters(1.0,1.0)
コード例 #3
0
def tst_ls_on_i():
  tmp = rs.xray_structure(sgtbx.space_group_info( 'P4' ),
                          elements=['C']*310,
                          n_scatterers=310)

  sfs = tmp.structure_factors( False, 3.5  ).f_calc()
  f_mod = xray.f_model_core_data( hkl = sfs.indices(),
                        f_atoms= sfs.data(),
                        f_mask = sfs.data(),
                        unit_cell = sfs.unit_cell(),
                        k_overall=1.0,
                        u_star=(0,0,0,0,0,0),
                        k_sol=0.0,
                        u_sol=0.0,
                        f_part=sfs.data(),
                        k_part=0.0,
                        u_part=0.0 )

  target_evaluator = xray.least_squares_hemihedral_twinning_on_i(
    hkl_obs=sfs.indices(),
    i_obs=( flex.abs(sfs.data())*flex.abs(sfs.data()))*1.0,
    w_obs=None,
    hkl_calc=sfs.indices(),
    space_group=sfs.space_group(),
    anomalous_flag=False,
    alpha=0.0,
    twin_law=[-1,0,0, 0,1,0, 0,0,-1]
    )

  target = target_evaluator.target( sfs.data() )
  # The target vaslue should be zero
  assert approx_equal( target, 0, eps=1e-6)

  # the derivatives as well
  derivs_complex = target_evaluator.d_target_d_fmodel( sfs.data()  )
  derivs_ab = target_evaluator.d_target_d_ab( sfs.data()  )
  for cmplx,da,db in zip(derivs_complex,
                         derivs_ab[0],
                         derivs_ab[1]):
    assert approx_equal( cmplx.real, da, eps=1e-5)
    assert approx_equal( cmplx.imag, db, eps=1e-5)

  for alpha in flex.double(range(50))/100.0:
    #----------------------------------------------------------------
    # use fin diffs to check the derivatives to a and b
    old_target_evaluator = xray.least_squares_hemihedral_twinning_on_i(
      hkl_obs=sfs.indices(),
      i_obs=( flex.abs(sfs.data())*flex.abs(sfs.data()))*1.1,
      w_obs=None,
      hkl_calc=sfs.indices(),
      space_group=sfs.space_group(),
      anomalous_flag=False,
      alpha=alpha,
      twin_law=[-1,0,0, 0,1,0, 0,0,-1]
      )
    old_target_value = old_target_evaluator.target( sfs.data() )
    old_derivs = old_target_evaluator.d_target_d_ab( sfs.data() )

    new_data =  sfs.data()
    h=0.0001

    for N_test in xrange(sfs.data().size() ):
      ori = complex( sfs.data()[N_test] )
      #print "----------------"
      #print alpha
      #print sfs.indices()[N_test]
      #print sfs.data()[N_test]
      new_data[N_test] = ori+complex(h,0)
      new_target_value = old_target_evaluator.target( new_data )
      fdif_real = float((new_target_value-old_target_value)/h)
      new_data[N_test] = ori+complex(0,h)
      new_target_value = old_target_evaluator.target( new_data )
      fdif_imag = float( (new_target_value-old_target_value)/h )
      # only use 'large' first derivatives.
      if old_derivs[0][N_test]>0:
        #print "real", N_test, fdif_real,old_derivs[0][N_test], (fdif_real-old_derivs[0][N_test])/old_derivs[0][N_test]
        if old_derivs[0][N_test]>2500:
          assert approx_equal( (fdif_real-old_derivs[0][N_test])/fdif_real,0, eps=1e-2)
      if old_derivs[1][N_test]>0:
        #print  "Imag", N_test, fdif_imag,old_derivs[1][N_test], (fdif_imag-old_derivs[1][N_test])/old_derivs[1][N_test]
        if old_derivs[1][N_test]>2500:
          assert approx_equal( (fdif_imag-old_derivs[1][N_test])/fdif_imag,0, eps=1e-2)
      new_data[N_test] = ori

  #-------------------------------------
  # use fin diffs to test derivatives wrst alpha, the twin fraction
  h=0.0000000001

  target_evaluator = xray.least_squares_hemihedral_twinning_on_i(
    hkl_obs=sfs.indices(),
    i_obs=( flex.abs(sfs.data())*flex.abs(sfs.data()))*1.0,
    w_obs=None,
    hkl_calc=sfs.indices(),
    space_group=sfs.space_group(),
    anomalous_flag=False,
    alpha=0,
    twin_law=[-1,0,0, 0,1,0, 0,0,-1]
    )

  tst_alpha = [0.1, 0.2, 0.3, 0.4, 0.5]

  for ii in tst_alpha:
    target_evaluator.alpha(ii)
    old_target = target_evaluator.target( sfs.data()*1.0 )
    target_evaluator.alpha( ii + h )
    new_target = target_evaluator.target( sfs.data()*1.0 )
    fd = (new_target-old_target)/h
    target_evaluator.alpha(ii)
    an = target_evaluator.d_target_d_alpha(sfs.data()*1.0)
    assert approx_equal( fd/an , 1.0, eps=1e-2 )