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

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 

5 

6 

7@dataclass 

8class BeamCard: 

9 """Class representing description of beam in Fluka input""" 

10 

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

12 

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 

38 

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] 

45 

46 beamposition_card = Card(codewd="BEAMPOS") 

47 

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 = "" 

53 

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 

62 

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