fd_generate.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/usr/bin/env python
  2. import argparse, os, sys
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. from numpy.lib.format import open_memmap
  6. from math import sqrt, pi
  7. # Parameters for test PDF function
  8. par = [ 9.50700e+04,
  9. 4.58242e+01,
  10. -1.21268e+01,
  11. -1.51309e+00,
  12. 2.38849e-01,
  13. -8.38068e+06,
  14. 3.34980e+01,
  15. 1.83062e+01,
  16. ]
  17. eLambda = 250
  18. def mkCache(base, name, shape, **kwargs):
  19. opath = os.path.join(base, "Data", name)
  20. try:
  21. os.makedirs(opath)
  22. except OSError:
  23. pass
  24. return { k : open_memmap(os.path.join(opath, k + ".npy"), dtype=t, mode='w+', shape=shape) for k, t in kwargs.items() }
  25. # Gaussian PDF
  26. def Gauss(x, u, s):
  27. return np.exp( -0.5*( (x-u)/s )**2 ) / sqrt(2*pi*s*s)
  28. def Exp(x, l):
  29. return np.exp(-x/l) / l
  30. # Background PDF
  31. def G_dijet5Param(x, com, *p):
  32. x[x < 0] = 0
  33. x[x > com] = com
  34. mX = x / com
  35. e = p[2] + p[3]*np.log(mX) + p[4]*np.log(x)**2
  36. return p[5]*Gauss(x,p[6],p[7]) + p[0] * (1-mX)**p[1] * mX**e
  37. ###### Okay, start it up.
  38. ArgP = argparse.ArgumentParser(description=' === Functional Decomposition Test Data Generator ===')
  39. ArgP.add_argument('--base', type=str, default=".", help="FD base directory.")
  40. ArgP.add_argument('--setname', type=str, default="Test", help="Name of dataset to create.")
  41. ArgP.add_argument('--varname', type=str, default="Mass", help="Variable name.")
  42. ArgP.add_argument('--wgtname', type=str, default="Wgt", help="Variable name.")
  43. ArgP.add_argument('--varcut', type=float, default=60.0, help="Minimum value for variable.")
  44. ArgP.add_argument('--com', type=float, default=13000, help="Center-of-mass energy.")
  45. ArgP.add_argument('--size', type=int, default=int(1e6), help="Number of events to create.")
  46. ArgP.add_argument('--cksize', type=int, default=int(1e6), help="Event creation chunk size.")
  47. ArgP.add_argument('--show', action='store_true', help="Show histogram of generated events before exit.")
  48. ArgC = ArgP.parse_args()
  49. ###### Initialize the variable and weight arrays.
  50. types = { ArgC.varname: np.float,
  51. ArgC.wgtname: np.float,
  52. }
  53. outSets = mkCache(ArgC.base, ArgC.setname, (ArgC.size,), **types)
  54. wgt = outSets[ArgC.wgtname]
  55. var = outSets[ArgC.varname]
  56. # get acceptance ratio
  57. x = np.linspace(ArgC.varcut, ArgC.com, 1e6)
  58. M = G_dijet5Param(x, ArgC.com, *par) / Exp(x - ArgC.varcut, eLambda)
  59. M = 1.01*M.max()
  60. # generate the data.
  61. n = 0
  62. ns = 0
  63. print
  64. print "======> FD TEST DATA GENERATOR <======"
  65. print
  66. while n < ArgC.size:
  67. x = ArgC.varcut + np.random.exponential(scale=eLambda, size=ArgC.cksize)
  68. u = np.random.uniform(size=ArgC.cksize)
  69. v = G_dijet5Param(x, ArgC.com, *par)
  70. keep = x[M * u < v / Exp(x - ArgC.varcut, eLambda) ]
  71. num = min(ArgC.size - n, len(keep) )
  72. var[n:n+num] = keep[:num]
  73. wgt[n:n+num] = 1.0
  74. n += num
  75. ns += 1
  76. print "\rGenerating: % 14d / % 9d" % ( n, ArgC.size ), ; sys.stdout.flush()
  77. print
  78. print "PDF Ratio: % 27.3f" % M
  79. print "Gen Efficiency: %22.3f" % ( float(ArgC.size) / float(ns*ArgC.cksize) )
  80. print
  81. if ArgC.show:
  82. plt.hist(var, 500, facecolor='g', alpha=0.75)
  83. plt.xlabel(ArgC.varname)
  84. plt.ylabel('Events')
  85. plt.title('Generated Events')
  86. plt.yscale('log')
  87. plt.xscale('log')
  88. plt.grid(True)
  89. plt.show()