class OneIndexLine(ValueLine): """A line with ``format(1x,I5,3x,1P,E16.8,0P,3x,'#',1x,A)``.""" _pattern = r"\s*" + cap(INT, "i") + SEP + cap(FLOAT, "value") + TAIL def __init__(self, i, value, comment=None): # type: (SInt, SValue, OS)->None super().__init__(int(i), value, comment)
class ThreeIndexLine(ValueLine): """A line with ``format(1x,I2,1x,I2,1x,I2,3x,1P,E16.8,0P,3x,'#',1x,A)``.""" _pattern = (r"\s*" + cap(INT, "i1") + SEP + cap(INT, "i2") + SEP + cap(INT, "i3") + SEP + cap(FLOAT, "value") + TAIL) def __init__(self, i1, i2, i3, value, comment=None): # type: (SInt, SInt, SInt, SValue, OS)->None super().__init__((int(i1), int(i2), int(i3)), value, comment)
class BlockHeadLine(AbsLine): """Line for block header.""" _pattern = ("Block" + SEP + cap(NAME, "name") + possible(SEP + r"Q=\s*" + cap(FLOAT, "q")) + TAIL) def __init__(self, name, q=None, comment=None): # type: (str, Optional[SFloat], OS)->None self.name = name self.q = None if q is None else _float(q) self.comment = comment or "" self.pre_comment = [] @property def name(self) -> str: """Return name in upper case.""" return self._name @name.setter def name(self, value: str) -> None: self._name = value.upper() def _to_slha(self, opt: LineOutputOption) -> str: if self.q is None: name = " {:17} ".format(self.name) else: name = " {} Q={} ".format(self.name, self._num_to_str(opt, self.q)) return (opt.block_str + name + self._format_comment(opt)).rstrip() def _dump(self) -> List[SFloat]: return [] if self.q is None else ["Q=", self.q] @classmethod def _from_dump(cls: Type[LT], dump: Sequence[Any], **kw: Any) -> LT: name = str(kw.get("name")) if not name or len(kw) > 1: raise ValueError(kw) if len(dump) == 0: return cls(name=name) elif len(dump) == 2: if isinstance(dump[0], str) and dump[0].strip().upper() == "Q=": return cls(name=name, q=_float(dump[1])) raise ValueError(dump) def _dump_comment(self) -> List[List[SFloat]]: comments = [["pre", "HEAD", c] for c in self.pre_comment] # type: List[List[SFloat]] if self.comment: comments.append(["HEAD", self.comment]) return comments
class NoIndexLine(ValueLine): """A line with ``format(9x, 1P, E16.8, 0P, 3x, '#', 1x, A)``.""" _pattern = r"\s*" + cap(FLOAT, "value") + TAIL def __init__(self, value, comment=None): # type: (SValue, OS)->None super().__init__(None, value, comment)
class InfoLine(AbsLine): """Class for lines of INFO blocks. An info-block line is given by ``format(1x,I5,3x,A)``, which is not exclusive and matches other patterns. This class accept multi-lines, and thus values are List[str] and comments are multi-lined string, internally kept as List[str]. """ _pattern = r"\s*" + cap(INT, "key") + SEP + cap(INFO, "value") + TAIL def __init__(self, key, value, comment=None): # type: (InfoKeyType, InfoValueType, OS)->None self.key = int(key) # type: InfoKeyType self.value = value.rstrip() # type: InfoValueType self.comment = comment or "" self.pre_comment = [] def _to_slha(self, opt: LineOutputOption) -> str: return " {:5d} {:16} {}".format(self.key, self.value, self._format_comment(opt)) def _dump(self) -> List[SFloat]: return [self.key, self.value] @classmethod def _from_dump(cls: Type["InfoLine"], dump: Sequence[Any], **kw: Any) -> LT: if kw: raise ValueError(kw) if len(dump) == 2: return cast(LT, cls(int(dump[0]), value=str(dump[1]))) raise ValueError(dump) def _dump_comment(self) -> List[List[SFloat]]: comments = [["pre", self.key, c] for c in self.pre_comment] # type: List[List[SFloat]] if self.comment: comments.append([self.key, self.comment]) return comments
class DecayHeadLine(AbsLine): """A line with format ``('DECAY',1x,I9,3x,1P,E16.8,0P,3x,'#',1x,A)``.""" _pattern = "Decay" + SEP + cap(INT, "pid") + SEP + cap(FLOAT, "width") + TAIL def __init__(self, pid: SInt, width: SFloat, comment: OS = None) -> None: self.pid = int(pid) self.width = _float(width) self.comment = comment or "" self.pre_comment = [] def _to_slha(self, opt: LineOutputOption) -> str: return "{decay} {pid:>9} {width} {comment}".format( decay=opt.decay_str, pid=self.pid, width=self._num_to_str(opt, self.width), comment=self._format_comment(opt), ) def _dump(self) -> List[SFloat]: return [self.width] @classmethod def _from_dump(cls: Type[LT], dump: Sequence[Any], **kw: Any) -> LT: pid = kw.get("pid") if not pid or len(kw) > 1: raise ValueError(kw) elif len(dump) == 1: return cls(pid=int(pid), width=_float(dump[0])) raise ValueError(dump) def _dump_comment(self) -> List[List[SFloat]]: comments = [["pre", "HEAD", c] for c in self.pre_comment] # type: List[List[SFloat]] if self.comment: comments.append(["HEAD", self.comment]) return comments
class DecayLine(ValueLine): """A decay line ``(3x,1P,E16.8,0P,3x,I2,3x,N (I9,1x),2x,'#',1x,A)``.""" _pattern = (r"\s*" + cap(FLOAT, "br") + SEP + cap(INT, "nda") + SEP + cap(r"[0-9\s+-]+", "channel") + TAIL) def __init__(self, br, channel, nda=None, comment=None): # type: (Union[str, DecayValueType], Union[str, DecayKeyType], Any, OS)->None if isinstance(channel, str): self.key = tuple(int(p) for p in re.split(r"\s+", channel.strip())) else: self.key = channel # type: DecayKeyType self.value = _float(br) # type: DecayValueType self.comment = comment or "" self.pre_comment = [] # provide synonym @property def br(self) -> DecayValueType: """Return the branching ratio.""" return self.value @br.setter def br(self, br: DecayValueType) -> None: self.value = br def _to_slha(self, opt: LineOutputOption) -> str: pids = "".join("{:9d} ".format(pid) for pid in self.key) return " {} {:2d} {} {}".format( self._num_to_str(opt, self.br), len(self.key), pids, self._format_comment(opt), ) def _dump(self) -> List[SFloat]: result = [self.br, len(self.key)] # type: List[SFloat] result.extend(self.key) return result @classmethod def _from_dump(cls: Type["DecayLine"], dump: Sequence[Any], **kw: Any) -> LT2: if kw: raise ValueError(kw) if len(dump) >= 4: br, nda = _float(dump[0]), int(dump[1]) pids = tuple(int(p) for p in dump[2:]) if nda == len(pids): return cast(LT2, cls(br=br, channel=pids)) raise ValueError(dump) def _dump_comment(self) -> List[List[SFloat]]: comments = [["pre", c] for c in self.pre_comment] # type: List[List[SFloat]] if self.comment: comments.append([self.comment]) for c in comments: c.extend(self.key) return comments