go-hep.org/x/hep@v0.38.1/slha/encode.go (about)

     1  // Copyright ©2017 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package slha
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"math"
    11  	"strings"
    12  )
    13  
    14  func blockFormat(name string, nargs int) string {
    15  	switch name {
    16  
    17  	case "MASS":
    18  		//return "(1x,I9,3x,1P,E16.8,0P,3x,’#’,1x,A)"
    19  		return " %9d   %16.8E   # %s\n"
    20  
    21  	case "NMIX", "UMIX", "VMIX", "STOPMIX", "SBOTMIX", "STAUMIX",
    22  		"USQMIX", "DSQMIX", "SELMIX", "SNUMIX", // FIXME(sbinet) right format ?
    23  		"AU", "AD", "AE",
    24  		"YU", "YD", "YE",
    25  		"TU", "TD", "TE",
    26  		"TUIN", "TDIN", "TEIN",
    27  		"MSQ2IN", "MSU2IN", "MSD2IN", "MSL2IN", "MSE2IN",
    28  		"MSQ2", "MSU2", "MSD2", "MSL2", "MSE2",
    29  		"VCKM", "IMVCKM",
    30  		"UPMNS", "IMUPMNS":
    31  		//return "(1x,I2,1x,I2,3x,1P,E16.8,0P,3x,’#’,1x,A)"
    32  		return " %2d %2d   %16.8E   # %s\n"
    33  
    34  	case "ALPHA":
    35  		// return "(9x,1P,E16.8,0P,3x,’#’,1x,A)"
    36  		return "         %16.8E   # %s\n"
    37  
    38  	case "HMIX",
    39  		"GAUGE",
    40  		"MSOFT":
    41  		//return "(1x,I5,3x,1P,E16.8,0P,3x,’#’,1x,A)"
    42  		return " %5d   %16.8E   # %s\n"
    43  
    44  	case "SMINPUTS", "VCKMIN", "UPMNSIN":
    45  		//return "(1x,I5,3x,A)"
    46  		return " %5d   %16.8E   # %s\n"
    47  
    48  	case "MINPAR", "EXTPAR", "QEXTPAR":
    49  		return " %5d   %16.8E   # %s\n"
    50  
    51  	case "SPINFO", "DCINFO":
    52  		return " %5d   %-8s    # %s\n"
    53  
    54  	case "MODSEL":
    55  		return " %5d %5d  # %s\n"
    56  
    57  	}
    58  
    59  	return strings.Repeat(" %v", nargs-1) + " # %s\n"
    60  }
    61  
    62  const (
    63  	particleHeader = "#         PDG            Width\n"
    64  	decayHeader    = "#          BR         NDA      ID1       ID2\n"
    65  	decayLineFront = "   %16.8E   %2d  "
    66  	decayLineID    = " %9d"
    67  	decayLineBack  = "   # %s\n"
    68  )
    69  
    70  // Encode writes the SLHA informations to w.
    71  func Encode(w io.Writer, data *SLHA) error {
    72  	var err error
    73  	for i := range data.Blocks {
    74  		blk := &data.Blocks[i]
    75  		str := []string{"BLOCK", blk.Name}
    76  		if !math.IsNaN(blk.Q) {
    77  			str = append(str, fmt.Sprintf("Q=%16.8E", blk.Q))
    78  		}
    79  		if blk.Comment != "" {
    80  			str = append(str, " # "+blk.Comment)
    81  		}
    82  		_, err = fmt.Fprintf(w, "%s\n", strings.Join(str, " "))
    83  		if err != nil {
    84  			return err
    85  		}
    86  
    87  		for _, item := range blk.Data {
    88  			v := item.Value
    89  			idx := item.Index.Index() //
    90  			args := make([]any, 0, len(idx)+2)
    91  			if blk.Name != "ALPHA" {
    92  				for _, v := range idx {
    93  					args = append(args, v)
    94  				}
    95  			}
    96  			args = append(args, v.Interface(), v.Comment())
    97  			format := blockFormat(blk.Name, len(args))
    98  			_, err = fmt.Fprintf(w, format, args...)
    99  			if err != nil {
   100  				return err
   101  			}
   102  		}
   103  		_, err = fmt.Fprintf(w, "#\n")
   104  		if err != nil {
   105  			return err
   106  		}
   107  	}
   108  
   109  	for i := range data.Particles {
   110  		part := &data.Particles[i]
   111  
   112  		_, err = fmt.Fprintf(w, "%sDECAY %9d   %16.8E   # %s\n", particleHeader, part.PdgID, part.Width, part.Comment)
   113  		if err != nil {
   114  			return err
   115  		}
   116  		if len(part.Decays) <= 0 {
   117  			_, err = fmt.Fprintf(w, "#\n")
   118  			if err != nil {
   119  				return err
   120  			}
   121  			continue
   122  		}
   123  
   124  		_, err = w.Write([]byte(decayHeader))
   125  		if err != nil {
   126  			return err
   127  		}
   128  
   129  		for j := range part.Decays {
   130  			decay := &part.Decays[j]
   131  			_, err = fmt.Fprintf(w, decayLineFront, decay.Br, len(decay.IDs))
   132  			if err != nil {
   133  				return err
   134  			}
   135  			for _, id := range decay.IDs {
   136  				_, err = fmt.Fprintf(w, decayLineID, id)
   137  				if err != nil {
   138  					return err
   139  				}
   140  			}
   141  			_, err = fmt.Fprintf(w, decayLineBack, decay.Comment)
   142  			if err != nil {
   143  				return err
   144  			}
   145  		}
   146  
   147  		_, err = fmt.Fprintf(w, "#\n")
   148  		if err != nil {
   149  			return err
   150  		}
   151  
   152  	}
   153  	return err
   154  }