Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:22:17

0001 #!/usr/bin/env python3
0002 
0003 
0004 import argparse
0005 import numpy
0006 import math
0007 import scipy.stats
0008 import random
0009 import collections
0010 import csv
0011 
0012 
0013 def neighbourhood(p, m):
0014     return [
0015         (x, y)
0016         for (x, y) in [
0017             (p[0] + 1, p[1]),
0018             (p[0] - 1, p[1]),
0019             (p[0] + 1, p[1] - 1),
0020             (p[0] - 1, p[1] - 1),
0021             (p[0] + 1, p[1] + 1),
0022             (p[0] - 1, p[1] + 1),
0023             (p[0], p[1] - 1),
0024             (p[0], p[1] + 1),
0025         ]
0026         if x >= 0 and y >= 0 and x < m and y < m
0027     ]
0028 
0029 
0030 def rand(d):
0031     return int(round(d.rvs()))
0032 
0033 
0034 def generate_file(name, Md, Hd, size, N):
0035     print("Generating file %s..." % name)
0036 
0037     with open(name, "w") as f:
0038         h = 0
0039         w = csv.DictWriter(
0040             f,
0041             fieldnames=[
0042                 "geometry_id",
0043                 "measurement_id",
0044                 "channel0",
0045                 "channel1",
0046                 "timestamp",
0047                 "value",
0048             ],
0049             lineterminator="\n",
0050         )
0051         w.writeheader()
0052 
0053         for m in range(N):
0054             acts = 0
0055             hits = rand(Md)
0056 
0057             points = set()
0058 
0059             for q in range(hits):
0060                 cells = rand(Hd)
0061                 center = (random.randint(0, size - 1), random.randint(0, size - 1))
0062 
0063                 cands = [center]
0064                 seen = set()
0065 
0066                 for c in range(cells):
0067                     if not cands:
0068                         break
0069 
0070                     p = random.choice(cands)
0071 
0072                     if p not in points:
0073                         w.writerow(
0074                             {
0075                                 "geometry_id": m,
0076                                 "measurement_id": h,
0077                                 "channel0": p[0],
0078                                 "channel1": p[1],
0079                                 "timestamp": 0,
0080                                 "value": random.uniform(0.1, 1.0),
0081                             }
0082                         )
0083 
0084                     acts += 1
0085 
0086                     seen.add(p)
0087                     cands += neighbourhood(p, size)
0088                     cands = [x for x in cands if x not in seen and x not in points]
0089 
0090                 h += 1
0091                 points |= seen
0092 
0093 
0094 if __name__ == "__main__":
0095     parser = argparse.ArgumentParser(description="Generate some CCL examples")
0096 
0097     parser.add_argument(
0098         "-C",
0099         type=int,
0100         help="number of files to generate",
0101     )
0102     parser.add_argument(
0103         "-N",
0104         type=int,
0105         default=2500,
0106         help="number of modules in the detector",
0107     )
0108     parser.add_argument(
0109         "-S",
0110         type=int,
0111         default=655,
0112         help="size of each module (SxS)",
0113     )
0114 
0115     parser.add_argument(
0116         "--Mm",
0117         type=float,
0118         default=1.65,
0119         help="mean hits per module",
0120     )
0121     parser.add_argument(
0122         "--Ms",
0123         type=float,
0124         default=0.95,
0125         help="scale of hits per module",
0126     )
0127 
0128     parser.add_argument(
0129         "--Hm",
0130         type=float,
0131         default=1.80,
0132         help="mean cells per hit",
0133     )
0134     parser.add_argument(
0135         "--Hs",
0136         type=float,
0137         default=0.89,
0138         help="scale of cells per hit",
0139     )
0140 
0141     parser.add_argument(
0142         "-o",
0143         type=str,
0144         default="ccl",
0145         help="output name",
0146     )
0147 
0148     args = parser.parse_args()
0149 
0150     hits_dist = scipy.stats.lognorm(args.Ms, scale=math.exp(args.Mm))
0151     cell_dist = scipy.stats.lognorm(args.Hs, scale=math.exp(args.Hm))
0152 
0153     print("Number of modules:               %d" % args.N)
0154     print("Module size:                     %dx%d" % (args.S, args.S))
0155     print("Total number of pixels:          %d" % (args.N * args.S * args.S))
0156     print()
0157     print(
0158         "Dist parameters hits per module: %s(μ=%.2f, σ=%.2f)"
0159         % (hits_dist.dist.name, args.Mm, args.Ms)
0160     )
0161     print(
0162         "Dist parameters cells per hit:   %s(μ=%.2f, σ=%.2f)"
0163         % (cell_dist.dist.name, args.Hm, args.Hs)
0164     )
0165     print()
0166     print("Expected hits per module:        %.2f" % hits_dist.mean())
0167     print("Expected total hits:             %.0f" % (args.N * hits_dist.mean()))
0168     print("Expected cells per hit:          %.2f" % cell_dist.mean())
0169     print(
0170         "Expected cells per module:       %.0f" % (cell_dist.mean() * hits_dist.mean())
0171     )
0172     print(
0173         "Expected total cells:            %.0f"
0174         % (args.N * cell_dist.mean() * hits_dist.mean())
0175     )
0176     print(
0177         "Expected density:                %.5f%%"
0178         % ((100 * hits_dist.mean() * cell_dist.mean()) / (args.S * args.S))
0179     )
0180     print()
0181 
0182     if args.C is None:
0183         generate_file(("%s.csv" % args.o), hits_dist, cell_dist, args.S, args.N)
0184     else:
0185         for i in range(args.C):
0186             generate_file(
0187                 "%s_%010d.csv" % (args.o, i), hits_dist, cell_dist, args.S, args.N
0188             )