def METHOD_NAME(miller_obs,
                        twin_law,
                        twin_fraction):
  # for the moment, ignore incompleten twin pairs please
  cb_op = sgtbx.change_of_basis_op( twin_law )
  twin_related_miller  = miller_obs.change_basis( cb_op ).set_observation_type(
    miller_obs )
  set1, set2 = miller_obs.common_sets( twin_related_miller )\
               .set_observation_type(miller_obs )
  assert miller_obs.observation_type() is not None
  assert miller_obs.sigmas() is not None
  if set1.is_xray_amplitude_array():
    set1 = set1.f_as_f_sq()
    set2 = set1.f_as_f_sq()
  detwinned_f     = flex.double()
  detwinned_sigma = flex.double()
  if set1.is_xray_intensity_array():
    if set2.is_xray_intensity_array():
      for i1,s1,i2,s2 in zip( set1.data(), set1.sigmas(),
                              set2.data(), set2.sigmas() ):
        tmp_detwinner = detwin(i1,s1,i2,s2)
        # we do some double work here actually
        ni1 = tmp_detwinner.xm
        ns1 = math.sqrt( math.abs(self.vcv[0]) )
        detwinned_f.append( ni1 )
        detwinned_s.append( ns1 )
  set1 = set1.f_sq_as_f()
  new_f = set1.customized_copy