code: def runMultiprocessNoiseExperiment(resultName, repeat, numWorkers,
                                     appendResults, **kwargs):
    
    experiments = [{}]
    for key, values in kwargs.items():
      if type(values) is list:
        newExperiments = []
        for experiment in experiments:
          for val in values:
            newExperiment = copy(experiment)
            newExperiment[key] = val
            newExperiments.append(newExperiment)
        experiments = newExperiments
      else:
        [a.__setitem__(key, values) for a in experiments]
  
    newExperiments = []
    for experiment in experiments:
      for _ in xrange(repeat):
        newExperiments.append(copy(experiment))
    experiments = newExperiments
  
    if numWorkers > 1:
      pool = Pool(processes=numWorkers)
      rs = pool.map_async(experimentWrapper, experiments, chunksize=1)
      while not rs.ready():
        remaining = rs._number_left
        pctDone = 100.0 - (100.0*remaining) / len(experiments)
        print "    =>", remaining, "experiments remaining, percent complete=",pctDone
        time.sleep(5)
      pool.close()  # No more work
      pool.join()
      result = rs.get()
    else:
      result = []
      for arg in experiments:
        result.append(doExperiment(**arg))
  
    # Save results for later use
    results = [(arg,res) for arg, res in zip(experiments, result)]
  
    if appendResults:
      try:
        with open(os.path.join(SCRIPT_DIR, resultName), "r") as f:
          existingResults = json.load(f)
          results = existingResults + results
      except IOError:
        pass
  
    with open(os.path.join(SCRIPT_DIR, resultName),"wb") as f:
      print "Writing results to {}".format(resultName)
      json.dump(results,f)
  
    return results
docs: :param kwargs: Pass lists to distribute as lists, lists that should be passed intact as tuples.
    :return: results, in the format [(arguments, results)].  Also saved to json at resultName, in the same format.