Coverage for yaptide/converter/converter/fluka/cards/beam_card.py: 75%
52 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-07-01 12:55 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-07-01 12:55 +0000
1from dataclasses import dataclass, field
2from converter.common import format_float
3from converter.fluka.cards.card import Card
4from converter.fluka.helper_parsers.beam_parser import BeamShape, FlukaBeam
7@dataclass
8class BeamCard:
9 """Class representing description of beam in Fluka input"""
11 data: FlukaBeam = field(default_factory=lambda: FlukaBeam()) # skipcq: PYL-W0108
13 def __str__(self) -> str:
14 """Return the card as a string."""
15 beam_card = Card(codewd="BEAM")
16 if self.data.shape == BeamShape.GAUSSIAN:
17 shape_what = -1
18 x_y_multiplier = -1
19 elif self.data.shape == BeamShape.CIRCULAR:
20 shape_what = -1
21 x_y_multiplier = 1
22 else:
23 shape_what = 0
24 x_y_multiplier = 1
25 # in Fluka input file positive number is interpreted as momentum
26 # and negative as energy
27 # we store energy in FlukaBeam object as positive number,
28 # so we need to multiply it by -1
29 # we also divide it by 1000 to convert from MeV to GeV
30 momentum_or_energy = format_float(-self.data.energy_MeV / 1000, 10)
31 shape_x = format_float(self.data.shape_x*x_y_multiplier, 10)
32 shape_y = format_float(self.data.shape_y*x_y_multiplier, 10)
33 if self.data.shape == BeamShape.CIRCULAR:
34 # swap x and y if beam is circular
35 # as circular beam is defined maximum and minimum radius in that order
36 # and in radius is provided in y
37 shape_x, shape_y = shape_y, shape_x
39 beam_card.what = [momentum_or_energy, 0, 0,
40 shape_x, shape_y, shape_what]
41 beam_card.sdum = self.data.particle_name
42 if self.data.particle_name == "HEAVYION":
43 hi_card = Card(codewd="HI-PROPE")
44 hi_card.what = [self.data.heavy_ion_z, self.data.heavy_ion_a, 0, 0, 0, 0]
46 beamposition_card = Card(codewd="BEAMPOS")
48 # z_negative is True if beam direction is negative in respect to z axis
49 if self.data.z_negative:
50 z_sdum = "NEGATIVE"
51 else:
52 z_sdum = ""
54 pos_x = format_float(self.data.beam_pos[0], 10)
55 pos_y = format_float(self.data.beam_pos[1], 10)
56 pos_z = format_float(self.data.beam_pos[2], 10)
57 dir_x = format_float(self.data.beam_dir[0], 10)
58 dir_y = format_float(self.data.beam_dir[1], 10)
59 beamposition_card.what = [pos_x, pos_y, pos_z,
60 dir_x, dir_y, 0]
61 beamposition_card.sdum = z_sdum
63 result = f"* {self.data.particle_name} beam of energy {-momentum_or_energy} GeV\n"
64 if self.data.shape == BeamShape.CIRCULAR:
65 result += f"* {self.data.shape} shape with max radius={shape_x} cm, min radius={shape_y} cm\n"
66 else:
67 result += f"* {self.data.shape} shape with x={shape_x} cm, y={shape_y} cm\n"
68 result += beam_card.__str__() + "\n"
69 if self.data.particle_name == "HEAVYION":
70 result += f"* heavy ion properties: a={self.data.heavy_ion_a}, z={self.data.heavy_ion_z}\n"
71 result += hi_card.__str__() + "\n"
72 result += (f"* beam position: ({pos_x}, {pos_y}, {pos_z}) cm\n"
73 f"* beam direction cosines in respect to x: {dir_x}, y: {dir_y}\n")
74 if self.data.z_negative:
75 result += "* beam direction is negative in respect to z axis\n"
76 else:
77 result += "* beam direction is positive in respect to z axis\n"
78 result += beamposition_card.__str__()
79 return result