Skip to content

beam_card

converter.converter.fluka.cards.beam_card

BeamCard dataclass

Class representing description of beam in Fluka input

Source code in yaptide/converter/converter/fluka/cards/beam_card.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
@dataclass
class BeamCard:
    """Class representing description of beam in Fluka input"""

    data: FlukaBeam = field(default_factory=lambda: FlukaBeam())  # skipcq: PYL-W0108

    def __str__(self) -> str:
        """Return the card as a string."""
        beam_card = Card(codewd="BEAM")
        if self.data.shape == BeamShape.GAUSSIAN:
            shape_what = -1
            x_y_multiplier = -1
        elif self.data.shape == BeamShape.CIRCULAR:
            shape_what = -1
            x_y_multiplier = 1
        else:
            shape_what = 0
            x_y_multiplier = 1
        # in Fluka input file positive number is interpreted as momentum
        # and negative as energy
        # we store energy in FlukaBeam object as positive number,
        # so we need to multiply it by -1
        # we also divide it by 1000 to convert from MeV to GeV
        momentum_or_energy = format_float(-self.data.energy_MeV / 1000, 10)
        shape_x = format_float(self.data.shape_x*x_y_multiplier, 10)
        shape_y = format_float(self.data.shape_y*x_y_multiplier, 10)
        if self.data.shape == BeamShape.CIRCULAR:
            # swap x and y if beam is circular
            # as circular beam is defined maximum and minimum radius in that order
            # and in radius is provided in y
            shape_x, shape_y = shape_y, shape_x

        beam_card.what = [momentum_or_energy, 0, 0,
                          shape_x, shape_y, shape_what]
        beam_card.sdum = self.data.particle_name
        if self.data.particle_name == "HEAVYION":
            hi_card = Card(codewd="HI-PROPE")
            hi_card.what = [self.data.heavy_ion_z, self.data.heavy_ion_a, 0, 0, 0, 0]

        beamposition_card = Card(codewd="BEAMPOS")

        # z_negative is True if beam direction is negative in respect to z axis
        if self.data.z_negative:
            z_sdum = "NEGATIVE"
        else:
            z_sdum = ""

        pos_x = format_float(self.data.beam_pos[0], 10)
        pos_y = format_float(self.data.beam_pos[1], 10)
        pos_z = format_float(self.data.beam_pos[2], 10)
        dir_x = format_float(self.data.beam_dir[0], 10)
        dir_y = format_float(self.data.beam_dir[1], 10)
        beamposition_card.what = [pos_x, pos_y, pos_z,
                                  dir_x, dir_y, 0]
        beamposition_card.sdum = z_sdum

        result = f"* {self.data.particle_name} beam of energy {-momentum_or_energy} GeV\n"
        if self.data.shape == BeamShape.CIRCULAR:
            result += f"* {self.data.shape} shape with max radius={shape_x} cm, min radius={shape_y} cm\n"
        else:
            result += f"* {self.data.shape} shape with x={shape_x} cm, y={shape_y} cm\n"
        result += beam_card.__str__() + "\n"
        if self.data.particle_name == "HEAVYION":
            result += f"* heavy ion properties: a={self.data.heavy_ion_a}, z={self.data.heavy_ion_z}\n"
            result += hi_card.__str__() + "\n"
        result += (f"* beam position: ({pos_x}, {pos_y}, {pos_z}) cm\n"
                   f"* beam direction cosines in respect to x: {dir_x}, y: {dir_y}\n")
        if self.data.z_negative:
            result += "* beam direction is negative in respect to z axis\n"
        else:
            result += "* beam direction is positive in respect to z axis\n"
        result += beamposition_card.__str__()
        return result

data class-attribute instance-attribute

data = field(default_factory=lambda: FlukaBeam())

__init__

__init__(data=lambda: FlukaBeam()())

__str__

__str__()

Return the card as a string.

Source code in yaptide/converter/converter/fluka/cards/beam_card.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def __str__(self) -> str:
    """Return the card as a string."""
    beam_card = Card(codewd="BEAM")
    if self.data.shape == BeamShape.GAUSSIAN:
        shape_what = -1
        x_y_multiplier = -1
    elif self.data.shape == BeamShape.CIRCULAR:
        shape_what = -1
        x_y_multiplier = 1
    else:
        shape_what = 0
        x_y_multiplier = 1
    # in Fluka input file positive number is interpreted as momentum
    # and negative as energy
    # we store energy in FlukaBeam object as positive number,
    # so we need to multiply it by -1
    # we also divide it by 1000 to convert from MeV to GeV
    momentum_or_energy = format_float(-self.data.energy_MeV / 1000, 10)
    shape_x = format_float(self.data.shape_x*x_y_multiplier, 10)
    shape_y = format_float(self.data.shape_y*x_y_multiplier, 10)
    if self.data.shape == BeamShape.CIRCULAR:
        # swap x and y if beam is circular
        # as circular beam is defined maximum and minimum radius in that order
        # and in radius is provided in y
        shape_x, shape_y = shape_y, shape_x

    beam_card.what = [momentum_or_energy, 0, 0,
                      shape_x, shape_y, shape_what]
    beam_card.sdum = self.data.particle_name
    if self.data.particle_name == "HEAVYION":
        hi_card = Card(codewd="HI-PROPE")
        hi_card.what = [self.data.heavy_ion_z, self.data.heavy_ion_a, 0, 0, 0, 0]

    beamposition_card = Card(codewd="BEAMPOS")

    # z_negative is True if beam direction is negative in respect to z axis
    if self.data.z_negative:
        z_sdum = "NEGATIVE"
    else:
        z_sdum = ""

    pos_x = format_float(self.data.beam_pos[0], 10)
    pos_y = format_float(self.data.beam_pos[1], 10)
    pos_z = format_float(self.data.beam_pos[2], 10)
    dir_x = format_float(self.data.beam_dir[0], 10)
    dir_y = format_float(self.data.beam_dir[1], 10)
    beamposition_card.what = [pos_x, pos_y, pos_z,
                              dir_x, dir_y, 0]
    beamposition_card.sdum = z_sdum

    result = f"* {self.data.particle_name} beam of energy {-momentum_or_energy} GeV\n"
    if self.data.shape == BeamShape.CIRCULAR:
        result += f"* {self.data.shape} shape with max radius={shape_x} cm, min radius={shape_y} cm\n"
    else:
        result += f"* {self.data.shape} shape with x={shape_x} cm, y={shape_y} cm\n"
    result += beam_card.__str__() + "\n"
    if self.data.particle_name == "HEAVYION":
        result += f"* heavy ion properties: a={self.data.heavy_ion_a}, z={self.data.heavy_ion_z}\n"
        result += hi_card.__str__() + "\n"
    result += (f"* beam position: ({pos_x}, {pos_y}, {pos_z}) cm\n"
               f"* beam direction cosines in respect to x: {dir_x}, y: {dir_y}\n")
    if self.data.z_negative:
        result += "* beam direction is negative in respect to z axis\n"
    else:
        result += "* beam direction is positive in respect to z axis\n"
    result += beamposition_card.__str__()
    return result