go-hep.org/x/hep@v0.38.1/groot/cmd/root-ls/main.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 // root-ls lists the content of a ROOT file. 6 // 7 // Usage: root-ls [options] file1.root [file2.root [...]] 8 // 9 // ex: 10 // 11 // $> root-ls -t ./testdata/graphs.root ./testdata/small-flat-tree.root 12 // === [./testdata/graphs.root] === 13 // version: 60806 14 // TGraph tg graph without errors (cycle=1) 15 // TGraphErrors tge graph with errors (cycle=1) 16 // TGraphAsymmErrors tgae graph with asymmetric errors (cycle=1) 17 // 18 // === [./testdata/small-flat-tree.root] === 19 // version: 60804 20 // TTree tree my tree title (entries=100) 21 // Int32 "Int32/I" TBranch 22 // Int64 "Int64/L" TBranch 23 // UInt32 "UInt32/i" TBranch 24 // UInt64 "UInt64/l" TBranch 25 // Float32 "Float32/F" TBranch 26 // Float64 "Float64/D" TBranch 27 // ArrayInt32 "ArrayInt32[10]/I" TBranch 28 // ArrayInt64 "ArrayInt64[10]/L" TBranch 29 // ArrayUInt32 "ArrayInt32[10]/i" TBranch 30 // ArrayUInt64 "ArrayInt64[10]/l" TBranch 31 // ArrayFloat32 "ArrayFloat32[10]/F" TBranch 32 // ArrayFloat64 "ArrayFloat64[10]/D" TBranch 33 // N "N/I" TBranch 34 // SliceInt32 "SliceInt32[N]/I" TBranch 35 // SliceInt64 "SliceInt64[N]/L" TBranch 36 // SliceUInt32 "SliceInt32[N]/i" TBranch 37 // SliceUInt64 "SliceInt64[N]/l" TBranch 38 // SliceFloat32 "SliceFloat32[N]/F" TBranch 39 // SliceFloat64 "SliceFloat64[N]/D" TBranch 40 package main // import "go-hep.org/x/hep/groot/cmd/root-ls" 41 42 import ( 43 "bufio" 44 "errors" 45 "flag" 46 "fmt" 47 "io" 48 "log" 49 "os" 50 "runtime/pprof" 51 52 "go-hep.org/x/hep/groot/rcmd" 53 _ "go-hep.org/x/hep/groot/riofs/plugin/http" 54 _ "go-hep.org/x/hep/groot/riofs/plugin/xrootd" 55 _ "go-hep.org/x/hep/groot/ztypes" 56 ) 57 58 var ( 59 fset = flag.NewFlagSet("ls", flag.ContinueOnError) 60 61 siFlag = fset.Bool("sinfos", false, "print StreamerInfos") 62 treeFlag = fset.Bool("t", false, "print Tree(s) (recursively)") 63 cpuFlag = fset.String("cpu-profile", "", "path to CPU profile output file") 64 65 usage = `Usage: root-ls [options] file1.root [file2.root [...]] 66 67 ex: 68 $> root-ls ./testdata/graphs.root 69 $> root-ls -t -sinfos ./testdata/graphs.root 70 71 options: 72 ` 73 ) 74 75 func main() { 76 os.Exit(run(os.Stdout, os.Stderr, os.Args[1:])) 77 } 78 79 func run(stdout, stderr io.Writer, args []string) int { 80 fset.Usage = func() { 81 fmt.Fprint(stderr, usage) 82 fset.PrintDefaults() 83 } 84 85 err := fset.Parse(args) 86 if err != nil { 87 if errors.Is(err, flag.ErrHelp) { 88 return 0 89 } 90 log.Printf("could not parse args %q: %+v", args, err) 91 return 1 92 } 93 94 if *cpuFlag != "" { 95 f, err := os.Create(*cpuFlag) 96 if err != nil { 97 log.Fatalf("%+v", err) 98 } 99 err = pprof.StartCPUProfile(f) 100 if err != nil { 101 log.Fatalf("could not start CPU profiling: %+v", err) 102 } 103 defer pprof.StopCPUProfile() 104 } 105 106 if fset.NArg() <= 0 { 107 fmt.Fprintf(stderr, "error: you need to give a ROOT file\n\n") 108 fset.Usage() 109 return 1 110 } 111 112 out := bufio.NewWriter(stdout) 113 defer out.Flush() 114 115 opts := []rcmd.ListOption{ 116 rcmd.ListStreamers(*siFlag), 117 rcmd.ListTrees(*treeFlag), 118 } 119 120 for ii, fname := range fset.Args() { 121 if ii > 0 { 122 fmt.Fprintf(out, "\n") 123 } 124 err := rcmd.List(out, fname, opts...) 125 if err != nil { 126 out.Flush() 127 log.Printf("%+v", err) 128 return 1 129 } 130 } 131 132 return 0 133 }