go-hep.org/x/hep@v0.38.1/cmd/fits2root/main_test.go (about)

     1  // Copyright ©2020 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 main
     6  
     7  import (
     8  	"os"
     9  	"path/filepath"
    10  	"reflect"
    11  	"strings"
    12  	"testing"
    13  
    14  	"codeberg.org/astrogo/fitsio"
    15  	"go-hep.org/x/hep/groot/rcmd"
    16  )
    17  
    18  func TestConvert(t *testing.T) {
    19  	tmp, err := os.MkdirTemp("", "fits2root-")
    20  	if err != nil {
    21  		t.Fatalf("%+v", err)
    22  	}
    23  	defer os.RemoveAll(tmp)
    24  
    25  	for _, tc := range []struct {
    26  		name string
    27  		cols []fitsio.Column
    28  		data any
    29  		want string
    30  	}{
    31  		{
    32  			name: "bools",
    33  			cols: []fitsio.Column{
    34  				{
    35  					Name:   "col",
    36  					Format: "L",
    37  				},
    38  			},
    39  			data: []bool{true, false, true, false, true},
    40  			want: `key[000]: test;1 "" (TTree)
    41  [000][col]: true
    42  [001][col]: false
    43  [002][col]: true
    44  [003][col]: false
    45  [004][col]: true
    46  `,
    47  		},
    48  		{
    49  			name: "i8",
    50  			cols: []fitsio.Column{
    51  				{
    52  					Name:   "col",
    53  					Format: "B",
    54  				},
    55  			},
    56  			data: []int8{10, 11, 12, 13, 14},
    57  			want: `key[000]: test;1 "" (TTree)
    58  [000][col]: 10
    59  [001][col]: 11
    60  [002][col]: 12
    61  [003][col]: 13
    62  [004][col]: 14
    63  `,
    64  		},
    65  		{
    66  			name: "i16",
    67  			cols: []fitsio.Column{
    68  				{
    69  					Name:   "col",
    70  					Format: "I",
    71  				},
    72  			},
    73  			data: []int16{10, 11, 12, 13, 14},
    74  			want: `key[000]: test;1 "" (TTree)
    75  [000][col]: 10
    76  [001][col]: 11
    77  [002][col]: 12
    78  [003][col]: 13
    79  [004][col]: 14
    80  `,
    81  		},
    82  		{
    83  			name: "i32",
    84  			cols: []fitsio.Column{
    85  				{
    86  					Name:   "col",
    87  					Format: "J",
    88  				},
    89  			},
    90  			data: []int32{10, 11, 12, 13, 14},
    91  			want: `key[000]: test;1 "" (TTree)
    92  [000][col]: 10
    93  [001][col]: 11
    94  [002][col]: 12
    95  [003][col]: 13
    96  [004][col]: 14
    97  `,
    98  		},
    99  		{
   100  			name: "i64",
   101  			cols: []fitsio.Column{
   102  				{
   103  					Name:   "col",
   104  					Format: "K",
   105  				},
   106  			},
   107  			data: []int64{-10, -11, -12, -13, -14},
   108  			want: `key[000]: test;1 "" (TTree)
   109  [000][col]: -10
   110  [001][col]: -11
   111  [002][col]: -12
   112  [003][col]: -13
   113  [004][col]: -14
   114  `,
   115  		},
   116  		{
   117  			name: "u8",
   118  			cols: []fitsio.Column{
   119  				{
   120  					Name:   "col",
   121  					Format: "B",
   122  				},
   123  			},
   124  			data: []uint8{10, 11, 12, 13, 14},
   125  			want: `key[000]: test;1 "" (TTree)
   126  [000][col]: 10
   127  [001][col]: 11
   128  [002][col]: 12
   129  [003][col]: 13
   130  [004][col]: 14
   131  `,
   132  		},
   133  		{
   134  			name: "u16",
   135  			cols: []fitsio.Column{
   136  				{
   137  					Name:   "col",
   138  					Format: "I",
   139  				},
   140  			},
   141  			data: []uint16{10, 11, 12, 13, 14},
   142  			want: `key[000]: test;1 "" (TTree)
   143  [000][col]: 10
   144  [001][col]: 11
   145  [002][col]: 12
   146  [003][col]: 13
   147  [004][col]: 14
   148  `,
   149  		},
   150  		{
   151  			name: "u32",
   152  			cols: []fitsio.Column{
   153  				{
   154  					Name:   "col",
   155  					Format: "J",
   156  				},
   157  			},
   158  			data: []uint32{10, 11, 12, 13, 14},
   159  			want: `key[000]: test;1 "" (TTree)
   160  [000][col]: 10
   161  [001][col]: 11
   162  [002][col]: 12
   163  [003][col]: 13
   164  [004][col]: 14
   165  `,
   166  		},
   167  		{
   168  			name: "u64",
   169  			cols: []fitsio.Column{
   170  				{
   171  					Name:   "col",
   172  					Format: "K",
   173  				},
   174  			},
   175  			data: []uint64{10, 11, 12, 13, 14},
   176  			want: `key[000]: test;1 "" (TTree)
   177  [000][col]: 10
   178  [001][col]: 11
   179  [002][col]: 12
   180  [003][col]: 13
   181  [004][col]: 14
   182  `,
   183  		},
   184  		{
   185  			name: "f32",
   186  			cols: []fitsio.Column{
   187  				{
   188  					Name:   "col",
   189  					Format: "E",
   190  				},
   191  			},
   192  			data: []float32{-10, -11, -12, -13, -14},
   193  			want: `key[000]: test;1 "" (TTree)
   194  [000][col]: -10
   195  [001][col]: -11
   196  [002][col]: -12
   197  [003][col]: -13
   198  [004][col]: -14
   199  `,
   200  		},
   201  		{
   202  			name: "f64",
   203  			cols: []fitsio.Column{
   204  				{
   205  					Name:   "col",
   206  					Format: "D",
   207  				},
   208  			},
   209  			data: []float64{-10, -11, -12, -13, -14},
   210  			want: `key[000]: test;1 "" (TTree)
   211  [000][col]: -10
   212  [001][col]: -11
   213  [002][col]: -12
   214  [003][col]: -13
   215  [004][col]: -14
   216  `,
   217  		},
   218  		{
   219  			name: "strings",
   220  			cols: []fitsio.Column{
   221  				{
   222  					Name:   "col",
   223  					Format: "10A",
   224  				},
   225  			},
   226  			data: []string{"a", "", "c ", " d", "eée", " "},
   227  			want: `key[000]: test;1 "" (TTree)
   228  [000][col]: a
   229  [001][col]: 
   230  [002][col]: c 
   231  [003][col]:  d
   232  [004][col]: eée
   233  [005][col]:  
   234  `,
   235  		},
   236  		{
   237  			name: "2df64",
   238  			cols: []fitsio.Column{
   239  				{
   240  					Name:   "col",
   241  					Format: "2D",
   242  				},
   243  			},
   244  			data: [][2]float64{{10, 11}, {12, 13}, {14, 15}, {16, 17}, {18, 19}},
   245  			want: `key[000]: test;1 "" (TTree)
   246  [000][col]: [10 11]
   247  [001][col]: [12 13]
   248  [002][col]: [14 15]
   249  [003][col]: [16 17]
   250  [004][col]: [18 19]
   251  `,
   252  		},
   253  	} {
   254  		t.Run(tc.name, func(t *testing.T) {
   255  			var (
   256  				fname = filepath.Join(tmp, tc.name+".fits")
   257  				oname = filepath.Join(tmp, tc.name+".root")
   258  			)
   259  
   260  			// create
   261  			func() {
   262  				w, err := os.Create(fname)
   263  				if err != nil {
   264  					t.Fatalf("%+v", err)
   265  				}
   266  				defer w.Close()
   267  
   268  				f, err := fitsio.Create(w)
   269  				if err != nil {
   270  					t.Fatalf("could not create input FITS file: %+v", err)
   271  				}
   272  				defer f.Close()
   273  
   274  				phdu, err := fitsio.NewPrimaryHDU(nil)
   275  				if err != nil {
   276  					t.Fatalf("could not create primary hdu: %+v", err)
   277  				}
   278  				err = f.Write(phdu)
   279  				if err != nil {
   280  					t.Fatalf("could not write primary hdu: %+v", err)
   281  				}
   282  
   283  				tbl, err := fitsio.NewTable("test", tc.cols, fitsio.BINARY_TBL)
   284  				if err != nil {
   285  					t.Fatalf("could not create FITS table: %+v", err)
   286  				}
   287  				defer tbl.Close()
   288  
   289  				rslice := reflect.ValueOf(tc.data)
   290  				for i := range rslice.Len() {
   291  					data := rslice.Index(i).Addr()
   292  					err = tbl.Write(data.Interface())
   293  					if err != nil {
   294  						t.Fatalf("could not write row [%v]: %+v", i, err)
   295  					}
   296  				}
   297  
   298  				err = f.Write(tbl)
   299  				if err != nil {
   300  					t.Fatalf("could not write FITS table: %+v", err)
   301  				}
   302  
   303  				err = f.Close()
   304  				if err != nil {
   305  					t.Fatalf("could not close FITS file: %+v", err)
   306  				}
   307  			}()
   308  
   309  			err := process(oname, "test", fname)
   310  			if err != nil {
   311  				t.Fatalf("could not convert FITS file: %+v", err)
   312  			}
   313  
   314  			// read-back
   315  			func() {
   316  				const deep = true
   317  				got := new(strings.Builder)
   318  				err := rcmd.Dump(got, oname, deep, nil)
   319  				if err != nil {
   320  					t.Fatalf("could not run root-dump: %+v", err)
   321  				}
   322  
   323  				if got, want := got.String(), tc.want; got != want {
   324  					t.Fatalf("fits2root conversion failed:\ngot:\n%s\nwant:\n%s\n", got, want)
   325  				}
   326  			}()
   327  		})
   328  	}
   329  }