go-hep.org/x/hep@v0.38.1/heppdt/parser.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 heppdt 6 7 import ( 8 "bufio" 9 "bytes" 10 "fmt" 11 "io" 12 "strconv" 13 ) 14 15 // parse fills a Table from the content of r 16 func parse(r io.Reader, table *Table) error { 17 var err error 18 s := bufio.NewScanner(r) 19 lineno := 0 20 for s.Scan() { 21 lineno++ 22 err = s.Err() 23 if err != nil { 24 break 25 } 26 bline := s.Bytes() 27 bline = bytes.Trim(bline, " \t\r\n") 28 if len(bline) <= 0 { 29 continue 30 } 31 if bline[0] == '#' { 32 continue 33 } 34 if len(bline) >= 2 && string(bline[:2]) == "//" { 35 continue 36 } 37 toks := bytes.Split(bline, []byte(" ")) 38 tokens := make([]string, 0, len(toks)) 39 for _, tok := range toks { 40 //fmt.Printf("--> [%s] => ", string(tok)) 41 tok = bytes.Trim(tok, " \t\r\n") 42 //fmt.Printf("[%s]\n", string(tok)) 43 if len(tok) > 0 { 44 tokens = append(tokens, string(tok)) 45 } 46 } 47 if len(tokens) != 6 { 48 stoks := "" 49 for i, tok := range tokens { 50 stoks += fmt.Sprintf("%q", tok) 51 if i != len(tokens)-1 { 52 stoks += ", " 53 } 54 } 55 //fmt.Printf("** error: line %d (%d): %v\n", lineno, len(tokens), stoks) 56 return fmt.Errorf("heppdt: malformed line:%d: %v", lineno, string(bline)) 57 } 58 var id int64 59 id, err = strconv.ParseInt(tokens[0], 10, 64) 60 if err != nil { 61 return fmt.Errorf("heppdt: line:%d: %w", lineno, err) 62 } 63 pid := PID(id) 64 65 name := string(tokens[1]) 66 67 var icharge int64 68 icharge, err = strconv.ParseInt(tokens[2], 10, 64) 69 if err != nil { 70 return fmt.Errorf("heppdt: line:%d: %w", lineno, err) 71 } 72 var charge float64 73 // allow for Q-balls 74 if pid.IsQBall() { 75 // 10x the charge 76 charge = float64(icharge) * 0.01 77 } else { 78 // 3x the charge 79 const onethird = 1. / 3.0 80 charge = float64(icharge) * onethird 81 } 82 var mass float64 83 mass, err = strconv.ParseFloat(tokens[3], 64) 84 if err != nil { 85 return fmt.Errorf("heppdt: line:%d: %w", lineno, err) 86 } 87 88 var totwidth float64 89 totwidth, err = strconv.ParseFloat(tokens[4], 64) 90 if err != nil { 91 return fmt.Errorf("heppdt: line:%d: %w", lineno, err) 92 } 93 94 var lifetime float64 95 lifetime, err = strconv.ParseFloat(tokens[5], 64) 96 if err != nil { 97 return fmt.Errorf("heppdt: line:%d: %w", lineno, err) 98 } 99 100 res := Resonance{ 101 Mass: Measurement{ 102 Value: mass, 103 Sigma: 0, 104 }, 105 } 106 107 // either width or lifetime is defined. not both. 108 switch { 109 case totwidth > 0.: 110 res.Width = Measurement{ 111 Value: totwidth, 112 Sigma: 0, 113 } 114 case totwidth == -1.: 115 res.Width = Measurement{ 116 Value: -1., 117 Sigma: 0., 118 } 119 case lifetime > 0.: 120 res.Width = Measurement{ 121 Value: calcWidthFromLifetime(lifetime), 122 Sigma: 0., 123 } 124 default: 125 res.Width = Measurement{} 126 } 127 128 part := Particle{ 129 ID: pid, 130 Name: name, 131 PDG: int(id), 132 Mass: mass, 133 Charge: charge, 134 Resonance: res, 135 } 136 table.pdt[pid] = &part 137 table.pid[name] = pid 138 //fmt.Printf(">>> %d: [%s]\n", lineno, tokens) 139 } 140 if err == io.EOF { 141 err = nil 142 } 143 144 return err 145 }