Beispiel #1
0
 def update_histo(self):
     if len(self.position) > 0:
         M_position = compton.transform(self.M, np.array(self.position))
         B, _ = np.histogramdd(M_position,
                               self.bin_edges,
                               weights=np.array(self.edep))
         self.hist += B
         self.position = []
         self.edep = []
def calc_vectorfield(conf):
    M = compton.build_transformation(conf['Slab']['Transformation'], mm, deg)
    M = inv(M)
    grid = np.array(conf['Slab']['Volume']) * mm
    dx = np.array(conf['VectorField']['GridResolution']) * mm

    result = []
    with h5py.File(conf['VectorField']['Input'], 'r') as fin:
        for group_name, gin in tqdm.tqdm(fin.items(),
                                         bar_format=fmt,
                                         desc='Reading trajectories'):

            x = gin['x'][:] * meter
            Mx = np.array([compton.transform(M, q) for q in x])
            grid_mask = compton.in_volume(grid, Mx)
            grid_mask += shift(grid_mask, -10) + shift(grid_mask, 1)
            Mx = Mx[grid_mask].copy()
            delta = np.diff(Mx, axis=0)
            n = delta / norm(delta, axis=1, keepdims=True)
            result.append(np.array((Mx[:-1], n)))
    x, n = np.hstack(result)
    mirror_x = x * np.array((1, -1, 1))

    bar = tqdm.tqdm(total=4,
                    bar_format=fmt,
                    desc='Creating smooth vectorfield')
    delaunay = spatial.Delaunay(np.concatenate((x, mirror_x)))
    bar.update(1)
    nearest_interp = NearestNDInterpolator(x, n)
    linear_interp = LinearNDInterpolator(x, n)
    bar.update(1)
    epsilon = 0.1 * dx
    dims = [np.arange(grid[q, 0], grid[q, 1] + epsilon, dx) for q in [0, 1, 2]]

    # Use linear interpolation within convex hull, else use nearest-neighbor.
    X, Y, Z = np.meshgrid(*dims, indexing='ij')
    n_XYZ = linear_interp((X, np.abs(Y), Z))
    bar.update(1)
    n_XYZ_nearest = nearest_interp((X, np.abs(Y), Z))
    bar.update(1)
    bar.close()
    mask = np.isnan(n_XYZ)
    n_XYZ[mask] = n_XYZ_nearest[mask]
    n_XYZ[Y < 0] *= np.array((1, -1, 1))

    if 'DiagnosticOutput' in conf['VectorField']:
        with h5py.File(conf['VectorField']['DiagnosticOutput'], 'w') as fout:
            fout['nx'] = n_XYZ[:, :, :, 0]
            fout['ny'] = n_XYZ[:, :, :, 1]
            fout['nz'] = n_XYZ[:, :, :, 2]

    interpolator = RegularGridInterpolator(dims,
                                           n_XYZ,
                                           bounds_error=False,
                                           fill_value=None)
    return interpolator, delaunay
def plot_sextupole_magnet_profile(ax, conf):
    from numpy.linalg import inv
    M = compton.build_transformation(conf['Transformation'], mm, deg)
    Minv = inv(M)
    c0 = conf['c0'] * mm
    b1 = conf['b1'] * mm
    a0 = c0 * (3 * (b1 / c0)**2 - 1)**(1.0 / 3)

    from scipy.interpolate import interp1d
    y = np.arange(1, 90 * mm, 1.0 * mm)
    z = np.sqrt((y**3 + a0**3) / (3 * y))
    y_z = interp1d(z, y)
    zscint = np.arange(95, 300, 1.0 * mm)
    pos = np.array((np.zeros_like(zscint), np.zeros_like(zscint), zscint))
    tpos = np.array([compton.transform(M, x) for x in pos.T]).T
    tpos[1] = y_z(tpos[2])
    pos = np.array([compton.transform(Minv, x) for x in tpos.T]).T

    ax.plot(pos[2] / mm, pos[1] / mm, color='k', linewidth=0.4)
    ax.plot(pos[2] / mm, -pos[1] / mm, color='k', linewidth=0.4)
def project_histogram(filename, conf, indices):
    fin = h5py.File(filename, 'r')
    edep = fin['edep'][:] * keV
    pos = fin['position'][:] * mm
    num_events = fin['edep'].attrs['num_events']
    M = compton.build_transformation(conf, mm, deg)
    tpos = np.array([compton.transform(M, x) for x in pos])
    # from pyevtk.hl import pointsToVTK
    # pointsToVTK("tpos", *np.ascontiguousarray(tpos.T), data=None)
    H, edges = np.histogramdd(tpos,
                              tuple(x.vals for x in indices),
                              weights=(edep / num_events))
    return H, edges
Beispiel #5
0
 def ProcessHits(self, step, history):
     event_id = g4.gEventManager.GetConstCurrentEvent().GetEventID()
     if event_id != self.curr_event:
         self.curr_event = event_id
         self.tally = 0
     x = G4ThreeVector_to_list(step.GetPreStepPoint().GetPosition())
     Mx = compton.transform(self.M, np.array(x))
     if self.tally < self.threshold:
         if compton.in_volume(self.vol, np.array((Mx, )))[0]:
             self.tally += step.GetTotalEnergyDeposit()
             if self.tally >= self.threshold:
                 self.num_flagged += 1
                 if self.num_flagged <= self.limit_count:
                     g4.gApplyUICommand('/event/keepCurrentEvent')
def plot_sextupole_magnet_profile(ax, conf):
    from numpy.linalg import inv
    M = compton.build_transformation(conf['Transformation'], mm, deg)
    Minv = inv(M)
    c0 = conf['c0'] * mm
    b1 = conf['b1'] * mm
    xoff = conf['xoff'] * mm
    alpha0 = conf['alpha0'] * deg
    a0 = c0 * (3 * (b1 / c0)**2 - 1)**(1.0 / 3)
    y = np.arange(1 * mm, 200 * mm, 1 * mm)
    z = np.sqrt((y**3 + a0**3) / (3 * y))
    x = xoff + np.tan(alpha0) * z
    pos = np.array((x, y, z))
    tpos = np.array([compton.transform(M, x) for x in pos.T]).T
    _, yscint, zscint = tpos
    ax.plot(zscint / mm, yscint / mm, color='#cccccc', linewidth=0.4, zorder=1)
    ax.plot(zscint / mm,
            -yscint / mm,
            color='#cccccc',
            linewidth=0.4,
            zorder=1)
Beispiel #7
0
def main():
    common.setup_plot()

    energy = []
    position = []
    theta0 = 28.0 * deg

    M = compton.build_transformation(
        [['TranslateX', 'RotateY', 'TranslateZ'], [-40.1, -28.0, -30.0]], mm,
        deg)

    with h5py.File('trajectories/trajectories.h5', 'r') as fin:
        for gin in fin.values():
            E0 = get_energy(gin)
            x0 = gin['x'][0] * meter
            x1 = gin['x'][-1] * meter
            if x0[1] != 0.0:
                continue
            x1 = compton.transform(M, x1)
            energy.append(E0)
            position.append(x1[2])
    energy = np.array(energy)
    position = np.array(position)
    args = np.argsort(energy)
    energy = energy[args]
    position = position[args]

    mod = lmfit.Model(fit_func)
    params = mod.make_params(c0=0.0, c1=0.0, c2=0.0)

    result = mod.fit(data=energy / MeV, x=position, params=params)
    print(result.fit_report())

    v = result.params.valuesdict()
    print(v['c0'])
    print(v['c1'])
    print(v['c2'])

    x_fit = np.linspace(position[0], position[-1], 200)

    fig = plot.figure(figsize=(244.0 / 72, 120.0 / 72))
    ax = fig.add_subplot(1, 1, 1)

    ax.semilogy(x_fit / mm, result.eval(x=x_fit), linewidth=0.6)

    ax.semilogy(position / mm,
                energy / MeV,
                marker='.',
                ls='',
                markersize=0.001,
                color='k')

    ax.text(0.05,
            0.8,
            r'$E(z_s)/{\rm MeV} = \exp (c_0 + c_1 z_s + c_2 z_s^2)$',
            fontsize=7.0,
            transform=ax.transAxes)

    text = r'$c_0 = {:.3}$'.format(v['c0']) + '\n'
    text += r'$c_1 = {:.3}'.format(num2tex(v['c1'] * mm))
    text += r'\;{\rm mm}^{-1}$' + '\n'
    text += r'$c_2 = {:.3}'.format(num2tex(v['c2'] * mm**2))
    text += r'\;{\rm mm}^{-2}$' + '\n'
    print(text)
    ax.text(0.5, 0.2, text, transform=ax.transAxes)

    ax.set_xlabel(r'$z_s$ (mm)', labelpad=-1.0)
    ax.set_ylabel(r"Energy (MeV)", labelpad=2.0)
    # ax.set_xlim(0, 250)
    ax.set_ylim(0.1, 20)
    ax.xaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator())

    filename = 'out/energy-scale.pdf'
    os.makedirs(os.path.dirname(filename), exist_ok=True)
    plot.savefig(filename, transparent=True)
def calc_lattice(conf, interpolator, delaunay):
    bar = tqdm.tqdm(total=2, bar_format=fmt, desc='Creating pore lattice')
    pore_conf = conf['Pores']
    a = pore_conf['a'] * mm
    delta_z = pore_conf['delta_z'] * mm
    z0 = pore_conf['z0'] * mm
    lz = pore_conf['lz'] * mm
    ly = pore_conf['ly'] * mm
    magnet_buffer = pore_conf['MagnetBuffer'] * mm
    max_length = pore_conf['MaxLength'] * mm
    volume = np.array(conf['Slab']['Volume']) * mm
    M = compton.build_transformation(conf['Slab']['Transformation'], mm, deg)

    zy_lattice = gen_lattice_points(a, (0, lz), (-0.5 * ly, 0.5 * ly))
    zy_lattice += np.array((delta_z, 0))
    # zy --> xyz
    tri_lattice = np.hstack((volume[0, 0] * np.ones(
        (len(zy_lattice), 1)), np.flip(zy_lattice, axis=1)))

    tri_lattice = tri_lattice[tri_lattice[:, 2] > z0]
    tri_lattice = tri_lattice[delaunay.find_simplex(tri_lattice) >= 0]
    bar.update(1)
    M_tri_lattice = np.array([compton.transform(M, q) for q in tri_lattice])

    # discard lattice points within a given distance from magnet pole
    tri_lattice = tri_lattice[calculate_pole_mask(conf, M_tri_lattice,
                                                  magnet_buffer)]
    bar.update(1)
    bar.close()

    hex_lattice = {}
    N = 6
    phi = (30 * deg) + np.linspace(0, 2 * np.pi, N, endpoint=False)
    hex_coords = (a / np.sqrt(3)) * np.array(
        (np.zeros_like(phi), np.sin(phi), np.cos(phi))).T

    # integrate hexagonal lattice through vectorfield
    for i, p in tqdm.tqdm(list(enumerate(tri_lattice)),
                          bar_format=fmt,
                          desc='Integrating lattice trajectories'):
        for q in hex_coords:
            coord = p + q
            key = (round(coord[1], 3), round(coord[2], 3))
            if key in hex_lattice:
                continue
            if delaunay.find_simplex(coord) == -1:
                # hex lattice point is outside trajectory hull
                hex_lattice[key] = None
                continue
            trajectory = calc_trajectory(interpolator, coord, max_length)
            if trajectory == None:
                # trajectory didn't cross x=0 plane
                hex_lattice[key] = None
                continue
            hex_lattice[key] = trajectory

    # assemble result
    result = []
    for p in tri_lattice:
        valid_hex = True
        trajectories = []
        for q in hex_coords:
            coord = p + q
            key = (round(coord[1], 3), round(coord[2], 3))
            if hex_lattice[key] == None:
                valid_hex = False
                break
            trajectories.append(hex_lattice[key])
        if valid_hex:
            result.append(trajectories)
    return result
Beispiel #9
0
def main():
    args = get_args()
    conf = args.conf

    # create safe interpreter for evaluation of configuration expressions
    aeval = asteval.Interpreter(use_numpy=True)
    for q in common.units.__all__:
        aeval.symtable[q] = common.units.__dict__[q]

    pconf = conf['Projection']
    M = compton.build_transformation(pconf['Transformation'], mm, deg)
    prefilter = np.array(pconf['Prefilter']) * mm
    postfilter = np.array(pconf['Postfilter']) * mm

    energy = []
    position = []

    x = []
    E0 = []
    with h5py.File(conf['Files']['Input'], 'r') as fin:
        for gin in fin.values():
            x.append((gin['x'][0] * meter,
                      compton.transform(M, gin['x'][-1] * meter)))
            E0.append(get_energy(gin))
    x = np.array(x)
    E0 = np.array(E0)
    prefilter_mask = compton.in_volume(prefilter, x[:, 0, :])
    x_pre = x[prefilter_mask, :, :]
    E0_pre = E0[prefilter_mask]
    postfilter_mask = compton.in_volume(postfilter, x_pre[:, 1, :])
    x_post = x_pre[postfilter_mask, :, :]
    E0_post = E0_pre[postfilter_mask]

    energy = E0_post.copy()
    position = x_post[:, 1, 2].copy()
    args = np.argsort(energy)
    energy = energy[args]
    position = position[args]

    mod = lmfit.Model(fit_func)
    params = mod.make_params(c0=0.0, c1=0.0, c2=0.0, c3=0.0)

    result = mod.fit(data=np.log(energy / MeV), x=position, params=params)

    v = result.params.valuesdict()
    x_fit = np.linspace(position[0], position[-1], 200)

    common.setup_plot()

    fig = plot.figure(figsize=np.array(conf['Plot']['FigSize']) / 72)
    ax = fig.add_subplot(1, 1, 1)

    axes = [get_axis(aeval, *conf['Plot'][x]) for x in ['XAxis', 'YAxis']]

    ax.semilogy(x_fit / axes[0].unit,
                np.exp(result.eval(x=x_fit)),
                linewidth=0.6)

    ax.semilogy(position / axes[0].unit,
                energy / axes[1].unit,
                marker='.',
                ls='',
                markersize=2.0,
                markeredgewidth=0,
                color='k')

    aeval.symtable['fitval'] = v
    aeval.symtable['num2tex'] = num2tex
    plot_annotation(ax, aeval, conf['Plot'])

    ax.set_xlabel(axes[0].label, labelpad=-1.0)
    ax.set_ylabel(axes[1].label, labelpad=2.0)

    ax.set_xlim(*axes[0].xlim)
    ax.set_ylim(*axes[1].xlim)
    ax.xaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator())

    filename = conf['Files']['PlotOutput']
    path = os.path.dirname(filename)
    if path != '':
        os.makedirs(path, exist_ok=True)
    plot.savefig(filename, transparent=True)

    if 'CalcOutput' in conf['Files']:
        filename = conf['Files']['CalcOutput']
        path = os.path.dirname(filename)
        if path != '':
            os.makedirs(path, exist_ok=True)
        calc_output = {
            'EnergyScaleCoefficients': {
                'c0': float(v['c0']),
                'c1': float(v['c1'] * mm),
                'c2': float(v['c2'] * mm**2),
                'c3': float(v['c3'] * mm**3)
            }
        }
        with open(filename, 'w') as fout:
            toml.dump(calc_output, fout)