Skip to main content
Solved

Create a halton sequence with python


Forum|alt.badge.img

Dear community,

I would like to create a halton sequence meaning systematic random distributed points. I found the appended python code. To call it: halton_sequence(

10
3
)
 Now, how can I adapt the code so I can use it in the PythonCreator? I would need a list of coordinates to create the points.

Thank you for your help!

 

0684Q00000ArFKEQA3.png

Best answer by david_r

Try the following in a PythonCreator:

import fmeobjects

def next_prime():
  Â  def is_prime(num):
  Â  Â  Â  "Checks if num is a prime value"
  Â  Â  Â  for i in range(2,int(num**0.5)+1):
  Â  Â  Â  Â  Â  if(num % i)==0return False
  Â  Â  Â  return True

  Â  prime = 3
  Â  while(1):
  Â  Â  Â  if is_prime(prime):
  Â  Â  Â  Â  Â  yield prime
  Â  Â  Â  prime += 2

def vdc(n, base=2):
  Â  vdc, denom = 01
  Â  while n:
  Â  Â  Â  denom *= base
  Â  Â  Â  n, remainder = divmod(n, base)
  Â  Â  Â  vdc += remainder/float(denom)
  Â  return vdc

def halton_sequence(size, dim):
  Â  seq = []
  Â  primeGen = next_prime()
  Â  next(primeGen)
  Â  for d in range(dim):
  Â  Â  Â  base = next(primeGen)
  Â  Â  Â  seq.append([vdc(i, base) for i in range(size)])
  Â  return seq


class FeatureCreator(object):
  Â  def __init__(self):
  Â  Â  Â  pass Â # Do nothing

  Â  def input(self,feature):
  Â  Â  Â  # Initialize the sequence
  Â  Â  Â  size = int(FME_MacroValues['HALTON_SIZE'])
  Â  Â  Â  dim = int(FME_MacroValues['HALTON_DIMENSION'])
  Â  Â  Â  halton = halton_sequence(size, dim)

  Â  Â  Â  if dim == 2:
  Â  Â  Â  Â  Â  halton_points = zip(halton[0], halton[1])
  Â  Â  Â  elif dim == 3:
  Â  Â  Â  Â  Â  halton_points = zip(halton[0], halton[1], halton[2])
  Â  Â  Â  else:
  Â  Â  Â  Â  Â  raise IndexError('Only 2 or 3 dimensions are supported')

  Â  Â  Â  for elem in halton_points:
  Â  Â  Â  Â  Â  newFeature = fmeobjects.FMEFeature()
  Â  Â  Â  Â  Â  if dim == 2:
  Â  Â  Â  Â  Â  Â  Â  newFeature.setDimension(fmeobjects.FME_TWO_D)
  Â  Â  Â  Â  Â  else:
  Â  Â  Â  Â  Â  Â  Â  newFeature.setDimension(fmeobjects.FME_THREE_D)
  Â  Â  Â  Â  Â  newFeature.addCoordinate(*elem)
  Â  Â  Â  Â  Â  self.pyoutput(newFeature)

  Â  def close(self):
  Â  Â  Â  pass Â # Do nothing

You'll have to create the two published parameters HALTON_SIZE and HALTON_DIMENSION in your workspace. The output will be either a number (HALTON_SIZE) points of either 2D or 3D points.

And since the upgrade forum software seems to struggle with code blocks, here's a workspace template (FME 2018.1): halton_sequence.fmwt

View original
Did this help you find an answer to your question?

4 replies

david_r
Celebrity
  • Best Answer
  • October 31, 2018

Try the following in a PythonCreator:

import fmeobjects

def next_prime():
  Â  def is_prime(num):
  Â  Â  Â  "Checks if num is a prime value"
  Â  Â  Â  for i in range(2,int(num**0.5)+1):
  Â  Â  Â  Â  Â  if(num % i)==0return False
  Â  Â  Â  return True

  Â  prime = 3
  Â  while(1):
  Â  Â  Â  if is_prime(prime):
  Â  Â  Â  Â  Â  yield prime
  Â  Â  Â  prime += 2

def vdc(n, base=2):
  Â  vdc, denom = 01
  Â  while n:
  Â  Â  Â  denom *= base
  Â  Â  Â  n, remainder = divmod(n, base)
  Â  Â  Â  vdc += remainder/float(denom)
  Â  return vdc

def halton_sequence(size, dim):
  Â  seq = []
  Â  primeGen = next_prime()
  Â  next(primeGen)
  Â  for d in range(dim):
  Â  Â  Â  base = next(primeGen)
  Â  Â  Â  seq.append([vdc(i, base) for i in range(size)])
  Â  return seq


class FeatureCreator(object):
  Â  def __init__(self):
  Â  Â  Â  pass Â # Do nothing

  Â  def input(self,feature):
  Â  Â  Â  # Initialize the sequence
  Â  Â  Â  size = int(FME_MacroValues['HALTON_SIZE'])
  Â  Â  Â  dim = int(FME_MacroValues['HALTON_DIMENSION'])
  Â  Â  Â  halton = halton_sequence(size, dim)

  Â  Â  Â  if dim == 2:
  Â  Â  Â  Â  Â  halton_points = zip(halton[0], halton[1])
  Â  Â  Â  elif dim == 3:
  Â  Â  Â  Â  Â  halton_points = zip(halton[0], halton[1], halton[2])
  Â  Â  Â  else:
  Â  Â  Â  Â  Â  raise IndexError('Only 2 or 3 dimensions are supported')

  Â  Â  Â  for elem in halton_points:
  Â  Â  Â  Â  Â  newFeature = fmeobjects.FMEFeature()
  Â  Â  Â  Â  Â  if dim == 2:
  Â  Â  Â  Â  Â  Â  Â  newFeature.setDimension(fmeobjects.FME_TWO_D)
  Â  Â  Â  Â  Â  else:
  Â  Â  Â  Â  Â  Â  Â  newFeature.setDimension(fmeobjects.FME_THREE_D)
  Â  Â  Â  Â  Â  newFeature.addCoordinate(*elem)
  Â  Â  Â  Â  Â  self.pyoutput(newFeature)

  Â  def close(self):
  Â  Â  Â  pass Â # Do nothing

You'll have to create the two published parameters HALTON_SIZE and HALTON_DIMENSION in your workspace. The output will be either a number (HALTON_SIZE) points of either 2D or 3D points.

And since the upgrade forum software seems to struggle with code blocks, here's a workspace template (FME 2018.1): halton_sequence.fmwt


david_r
Celebrity
  • October 31, 2018
david_r wrote:

Try the following in a PythonCreator:

import fmeobjects

def next_prime():
  Â  def is_prime(num):
  Â  Â  Â  "Checks if num is a prime value"
  Â  Â  Â  for i in range(2,int(num**0.5)+1):
  Â  Â  Â  Â  Â  if(num % i)==0return False
  Â  Â  Â  return True

  Â  prime = 3
  Â  while(1):
  Â  Â  Â  if is_prime(prime):
  Â  Â  Â  Â  Â  yield prime
  Â  Â  Â  prime += 2

def vdc(n, base=2):
  Â  vdc, denom = 01
  Â  while n:
  Â  Â  Â  denom *= base
  Â  Â  Â  n, remainder = divmod(n, base)
  Â  Â  Â  vdc += remainder/float(denom)
  Â  return vdc

def halton_sequence(size, dim):
  Â  seq = []
  Â  primeGen = next_prime()
  Â  next(primeGen)
  Â  for d in range(dim):
  Â  Â  Â  base = next(primeGen)
  Â  Â  Â  seq.append([vdc(i, base) for i in range(size)])
  Â  return seq


class FeatureCreator(object):
  Â  def __init__(self):
  Â  Â  Â  pass Â # Do nothing

  Â  def input(self,feature):
  Â  Â  Â  # Initialize the sequence
  Â  Â  Â  size = int(FME_MacroValues['HALTON_SIZE'])
  Â  Â  Â  dim = int(FME_MacroValues['HALTON_DIMENSION'])
  Â  Â  Â  halton = halton_sequence(size, dim)

  Â  Â  Â  if dim == 2:
  Â  Â  Â  Â  Â  halton_points = zip(halton[0], halton[1])
  Â  Â  Â  elif dim == 3:
  Â  Â  Â  Â  Â  halton_points = zip(halton[0], halton[1], halton[2])
  Â  Â  Â  else:
  Â  Â  Â  Â  Â  raise IndexError('Only 2 or 3 dimensions are supported')

  Â  Â  Â  for elem in halton_points:
  Â  Â  Â  Â  Â  newFeature = fmeobjects.FMEFeature()
  Â  Â  Â  Â  Â  if dim == 2:
  Â  Â  Â  Â  Â  Â  Â  newFeature.setDimension(fmeobjects.FME_TWO_D)
  Â  Â  Â  Â  Â  else:
  Â  Â  Â  Â  Â  Â  Â  newFeature.setDimension(fmeobjects.FME_THREE_D)
  Â  Â  Â  Â  Â  newFeature.addCoordinate(*elem)
  Â  Â  Â  Â  Â  self.pyoutput(newFeature)

  Â  def close(self):
  Â  Â  Â  pass Â # Do nothing

You'll have to create the two published parameters HALTON_SIZE and HALTON_DIMENSION in your workspace. The output will be either a number (HALTON_SIZE) points of either 2D or 3D points.

And since the upgrade forum software seems to struggle with code blocks, here's a workspace template (FME 2018.1): halton_sequence.fmwt

@NatalieAtSafe Could you please have a look at the code block formatting, please? Something weird is going on after the forum upgrade...


david_r
Celebrity
  • October 31, 2018

Next time, please consider either using a code block or giving the URL to source of the code so that we can copy/paste it rather than type from images :-)


Forum|alt.badge.img
david_r wrote:

Try the following in a PythonCreator:

import fmeobjects

def next_prime():
  Â  def is_prime(num):
  Â  Â  Â  "Checks if num is a prime value"
  Â  Â  Â  for i in range(2,int(num**0.5)+1):
  Â  Â  Â  Â  Â  if(num % i)==0return False
  Â  Â  Â  return True

  Â  prime = 3
  Â  while(1):
  Â  Â  Â  if is_prime(prime):
  Â  Â  Â  Â  Â  yield prime
  Â  Â  Â  prime += 2

def vdc(n, base=2):
  Â  vdc, denom = 01
  Â  while n:
  Â  Â  Â  denom *= base
  Â  Â  Â  n, remainder = divmod(n, base)
  Â  Â  Â  vdc += remainder/float(denom)
  Â  return vdc

def halton_sequence(size, dim):
  Â  seq = []
  Â  primeGen = next_prime()
  Â  next(primeGen)
  Â  for d in range(dim):
  Â  Â  Â  base = next(primeGen)
  Â  Â  Â  seq.append([vdc(i, base) for i in range(size)])
  Â  return seq


class FeatureCreator(object):
  Â  def __init__(self):
  Â  Â  Â  pass Â # Do nothing

  Â  def input(self,feature):
  Â  Â  Â  # Initialize the sequence
  Â  Â  Â  size = int(FME_MacroValues['HALTON_SIZE'])
  Â  Â  Â  dim = int(FME_MacroValues['HALTON_DIMENSION'])
  Â  Â  Â  halton = halton_sequence(size, dim)

  Â  Â  Â  if dim == 2:
  Â  Â  Â  Â  Â  halton_points = zip(halton[0], halton[1])
  Â  Â  Â  elif dim == 3:
  Â  Â  Â  Â  Â  halton_points = zip(halton[0], halton[1], halton[2])
  Â  Â  Â  else:
  Â  Â  Â  Â  Â  raise IndexError('Only 2 or 3 dimensions are supported')

  Â  Â  Â  for elem in halton_points:
  Â  Â  Â  Â  Â  newFeature = fmeobjects.FMEFeature()
  Â  Â  Â  Â  Â  if dim == 2:
  Â  Â  Â  Â  Â  Â  Â  newFeature.setDimension(fmeobjects.FME_TWO_D)
  Â  Â  Â  Â  Â  else:
  Â  Â  Â  Â  Â  Â  Â  newFeature.setDimension(fmeobjects.FME_THREE_D)
  Â  Â  Â  Â  Â  newFeature.addCoordinate(*elem)
  Â  Â  Â  Â  Â  self.pyoutput(newFeature)

  Â  def close(self):
  Â  Â  Â  pass Â # Do nothing

You'll have to create the two published parameters HALTON_SIZE and HALTON_DIMENSION in your workspace. The output will be either a number (HALTON_SIZE) points of either 2D or 3D points.

And since the upgrade forum software seems to struggle with code blocks, here's a workspace template (FME 2018.1): halton_sequence.fmwt

This works perfectly. Thank you very much!


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings