go-hep.org/x/hep@v0.38.1/geo/gdml/solids_test.go (about)

     1  // Copyright ©2018 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 gdml
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/xml"
    10  	"reflect"
    11  	"testing"
    12  )
    13  
    14  func TestReadSolids(t *testing.T) {
    15  	for _, tc := range []struct {
    16  		name string
    17  		raw  string
    18  		want any
    19  	}{
    20  		{
    21  			name: "box",
    22  			raw:  `<box name="mybox" x="30" y="32" z="33" lunit="mm"/>`,
    23  			want: Box{Name: "mybox", X: "30", Y: "32", Z: "33", LUnit: "mm"},
    24  		},
    25  		{
    26  			name: "cone",
    27  			raw:  `<cone name="mycone" rmin1="10" rmax1="15" rmin2="20" rmax2="25" z="30" startphi="1" deltaphi="4" aunit="rad" lunit="mm"/>`,
    28  			want: Cone{
    29  				Name:  "mycone",
    30  				RMin1: "10", RMax1: "15", RMin2: "20", RMax2: "25", Z: "30", StartPhi: "1", DPhi: "4",
    31  				AUnit: "rad",
    32  				LUnit: "mm",
    33  			},
    34  		},
    35  		{
    36  			name: "ellipsoid",
    37  			raw:  `<ellipsoid name="myellipsoid" ax="10" by="15" cz="20" zcut1="2" zcut2="4" lunit="mm"/>`,
    38  			want: Ellipsoid{Name: "myellipsoid", Ax: "10", By: "15", Cz: "20", ZCut1: "2", ZCut2: "4", LUnit: "mm"},
    39  		},
    40  		{
    41  			name: "elliptical-tube",
    42  			raw:  `<eltube name="myeltube" dx="10" dy="15" dz="20" lunit="mm"/>`,
    43  			want: EllipticalTube{Name: "myeltube", Dx: "10", Dy: "15", Dz: "20", LUnit: "mm"},
    44  		},
    45  		{
    46  			name: "elliptical-cone",
    47  			raw:  `<elcone name="myelcone" dx="10" dy="15" zmax="2" zcut="1.5" lunit="mm"/>`,
    48  			want: EllipticalCone{Name: "myelcone", Dx: "10", Dy: "15", ZMax: "2", ZCut: "1.5", LUnit: "mm"},
    49  		},
    50  		{
    51  			name: "orb",
    52  			raw:  `<orb name="myorb" r="10" lunit="mm"/>`,
    53  			want: Orb{Name: "myorb", R: "10", LUnit: "mm"},
    54  		},
    55  		{
    56  			name: "paraboloid",
    57  			raw:  `<paraboloid name="parab" rlo="10" rhi="15" dz="20" aunit="rad" lunit="mm"/>`,
    58  			want: Paraboloid{Name: "parab", Rlo: "10", Rhi: "15", Dz: "20", AUnit: "rad", LUnit: "mm"},
    59  		},
    60  		{
    61  			name: "parallelepiped",
    62  			raw:  `<para name="para" x="10" y="11" z="12" alpha="1" theta="2" phi="3" aunit="rad" lunit="mm"/>`,
    63  			want: Parallelepiped{Name: "para", X: "10", Y: "11", Z: "12", Alpha: "1", Theta: "2", Phi: "3", AUnit: "rad", LUnit: "mm"},
    64  		},
    65  		{
    66  			name: "polycone",
    67  			raw: `
    68  			<polycone name="polycone" startphi="1" deltaphi="4" aunit="rad" lunit="mm">
    69  				<zplane rmin="1" rmax="9" z="10" />
    70  				<zplane rmin="3" rmax="5" z="12" />
    71  			</polycone>`,
    72  			want: PolyCone{
    73  				Name:     "polycone",
    74  				StartPhi: "1", DPhi: "4", AUnit: "rad", LUnit: "mm",
    75  				ZPlanes: []ZPlane{
    76  					{XMLName: xml.Name{Local: "zplane"}, RMin: "1", RMax: "9", Z: "10"},
    77  					{XMLName: xml.Name{Local: "zplane"}, RMin: "3", RMax: "5", Z: "12"},
    78  				},
    79  			},
    80  		},
    81  		{
    82  			name: "generic-polycone",
    83  			raw: `
    84  			<genericPolycone name="polycone" startphi="1" deltaphi="4" aunit="rad" lunit="mm">
    85  				<rzpoint r="1" z="5" />
    86  				<rzpoint r="3" z="10" />
    87  				<rzpoint r="1" z="12" />
    88  			</genericPolycone>`,
    89  			want: GenericPolyCone{
    90  				Name:     "polycone",
    91  				StartPhi: "1", DPhi: "4", AUnit: "rad", LUnit: "mm",
    92  				RZPoints: []RZPoint{
    93  					{XMLName: xml.Name{Local: "rzpoint"}, R: "1", Z: "5"},
    94  					{XMLName: xml.Name{Local: "rzpoint"}, R: "3", Z: "10"},
    95  					{XMLName: xml.Name{Local: "rzpoint"}, R: "1", Z: "12"},
    96  				},
    97  			},
    98  		},
    99  		{
   100  			name: "polyhedron",
   101  			raw: `
   102  			<polyhedra name="polyhedra" startphi="1" deltaphi="4" numsides="10" aunit="rad" lunit="mm">
   103  				<zplane rmin="1" rmax="9" z="10" />
   104  				<zplane rmin="3" rmax="5" z="12" />
   105  			</polyhedra>`,
   106  			want: PolyHedra{
   107  				Name:     "polyhedra",
   108  				StartPhi: "1", DPhi: "4", NumSides: "10", AUnit: "rad", LUnit: "mm",
   109  				ZPlanes: []ZPlane{
   110  					{XMLName: xml.Name{Local: "zplane"}, RMin: "1", RMax: "9", Z: "10"},
   111  					{XMLName: xml.Name{Local: "zplane"}, RMin: "3", RMax: "5", Z: "12"},
   112  				},
   113  			},
   114  		},
   115  		{
   116  			name: "generic-polyhedra",
   117  			raw: `
   118  			<genericPolyhedra name="polyhedra" startphi="1" deltaphi="4" numsides="10" aunit="rad" lunit="mm">
   119  				<rzpoint r="1" z="5" />
   120  				<rzpoint r="3" z="10" />
   121  				<rzpoint r="1" z="12" />
   122  			</genericPolyhedra>`,
   123  			want: GenericPolyHedra{
   124  				Name:     "polyhedra",
   125  				StartPhi: "1", DPhi: "4", NumSides: "10", AUnit: "rad", LUnit: "mm",
   126  				RZPoints: []RZPoint{
   127  					{XMLName: xml.Name{Local: "rzpoint"}, R: "1", Z: "5"},
   128  					{XMLName: xml.Name{Local: "rzpoint"}, R: "3", Z: "10"},
   129  					{XMLName: xml.Name{Local: "rzpoint"}, R: "1", Z: "12"},
   130  				},
   131  			},
   132  		},
   133  		{
   134  			name: "sphere",
   135  			raw:  `<sphere name="sphere" rmin="1" rmax="4" deltaphi="1" deltatheta="2" aunit="rad" lunit="mm"/>`,
   136  			want: Sphere{Name: "sphere", RMin: "1", RMax: "4", DPhi: "1", DTheta: "2", AUnit: "rad", LUnit: "mm"},
   137  		},
   138  		{
   139  			name: "torus",
   140  			raw:  `<torus name="torus" rmin="1" rmax="4" rtor="2" deltaphi="3" startphi="1" aunit="rad" lunit="mm"/>`,
   141  			want: Torus{Name: "torus", RMin: "1", RMax: "4", Rtor: "2", DPhi: "3", StartPhi: "1", AUnit: "rad", LUnit: "mm"},
   142  		},
   143  		{
   144  			name: "trapezoid",
   145  			raw:  `<trd name="trd" x1="9" x2="8" y1="6" y2="5" z="10" lunit="mm"/>`,
   146  			want: Trapezoid{Name: "trd", X1: "9", X2: "8", Y1: "6", Y2: "5", Z: "10", LUnit: "mm"},
   147  		},
   148  		{
   149  			name: "trap",
   150  			raw: `<trap name="trap" 
   151  				z="10" theta="1" phi="2" y1="15" x1="10" x2="10.1" alpha1="1.1"
   152  				y2="15.1" x3="10.3" x4="10.4" alpha2="1.2"
   153  				aunit="rad" lunit="mm"
   154  			/>`,
   155  			want: GeneralTrapezoid{
   156  				Name: "trap", AUnit: "rad", LUnit: "mm",
   157  				Z: "10", Theta: "1", Phi: "2",
   158  				Y1: "15", X1: "10",
   159  				X2:     "10.1",
   160  				Alpha1: "1.1",
   161  				Y2:     "15.1", X3: "10.3", X4: "10.4",
   162  				Alpha2: "1.2",
   163  			},
   164  		},
   165  		{
   166  			name: "hype",
   167  			raw:  `<hype name="hype" rmin="1" rmax="2" z="20" inst="3" outst="4" lunit="mm"/>`,
   168  			want: HyperbolicTube{Name: "hype", RMin: "1", RMax: "2", Z: "20", InStereo: "3", OutStereo: "4", LUnit: "mm"},
   169  		},
   170  		{
   171  			name: "cuttube",
   172  			raw: `<cutTube name="cuttube" z="20" rmin="1" rmax="5" startphi="1" deltaphi="4"
   173  				lowX="15" lowY="16" lowZ="17"
   174  				highX="20" highY="21" highZ="22"
   175  				aunit="rad" lunit="mm"
   176  			/>`,
   177  			want: CutTube{
   178  				Name: "cuttube", AUnit: "rad", LUnit: "mm",
   179  				Z: "20", RMin: "1", RMax: "5",
   180  				StartPhi: "1", DPhi: "4",
   181  				LowX: "15", LowY: "16", LowZ: "17",
   182  				HighX: "20", HighY: "21", HighZ: "22",
   183  			},
   184  		},
   185  		{
   186  			name: "tube",
   187  			raw:  `<tube name="tube" z="20" rmin="1" rmax="5" startphi="1" deltaphi="4" aunit="rad" lunit="mm" />`,
   188  			want: Tube{
   189  				Name: "tube", AUnit: "rad", LUnit: "mm",
   190  				Z: "20", RMin: "1", RMax: "5",
   191  				StartPhi: "1", DPhi: "4",
   192  			},
   193  		},
   194  		{
   195  			name: "twistedbox",
   196  			raw:  `<twistedbox name="twistbox" PhiTwist="1" x="30" y="32" z="33" aunit="rad" lunit="mm"/>`,
   197  			want: TwistedBox{Name: "twistbox", PhiTwist: "1", X: "30", Y: "32", Z: "33", AUnit: "rad", LUnit: "mm"},
   198  		},
   199  		{
   200  			name: "twistedtrapezoid",
   201  			raw:  `<twistedtrd name="twistedtrd" PhiTwist="1" x1="9" x2="8" y1="6" y2="5" z="10" aunit="rad" lunit="mm"/>`,
   202  			want: TwistedTrapezoid{Name: "twistedtrd", PhiTwist: "1", X1: "9", X2: "8", Y1: "6", Y2: "5", Z: "10", AUnit: "rad", LUnit: "mm"},
   203  		},
   204  		{
   205  			name: "twistedtrap",
   206  			raw: `<twistedtrap name="twistedtrap"
   207  				PhiTwist="1"
   208  				z="10" theta="1" phi="2" y1="15" x1="10" x2="10.1"
   209  				y2="15.1" x3="10.3" x4="10.4" Alph="1.2"
   210  				aunit="rad" lunit="mm"
   211  			/>`,
   212  			want: TwistedGeneralTrapezoid{
   213  				Name: "twistedtrap", AUnit: "rad", LUnit: "mm", PhiTwist: "1",
   214  				Z: "10", Theta: "1", Phi: "2",
   215  				Y1: "15", X1: "10",
   216  				X2: "10.1",
   217  				Y2: "15.1", X3: "10.3", X4: "10.4",
   218  				Alpha: "1.2",
   219  			},
   220  		},
   221  		{
   222  			name: "twistedtube",
   223  			raw: `<twistedtube name="twisttube" endinnerrad="1" endouterrad="2" zlen="3"
   224  				twistedangle="4"
   225  				phi="5"
   226  				midinnerrad="6" midouterrad="7"
   227  				nseg="8" totphi="9"
   228  				aunit="rad" lunit="mm"
   229  			/>`,
   230  			want: TwistedTube{
   231  				Name: "twisttube", AUnit: "rad", LUnit: "mm",
   232  				EndInnerRad: "1", EndOuterRad: "2",
   233  				ZLen:         "3",
   234  				TwistedAngle: "4",
   235  				Phi:          "5",
   236  				MidInnerRad:  "6", MidOuterRad: "7",
   237  				NSeg: "8", TotPhi: "9",
   238  			},
   239  		},
   240  		{
   241  			name: "xtru",
   242  			raw: `<xtru name="xtru" lunit="mm" >
   243  				<twoDimVertex x="3" y="9" />
   244  				<twoDimVertex x="1" y="5" />
   245  				<twoDimVertex x="2" y="4" />
   246  				<section zOrder="1" zPosition="2" xOffset="5" yOffset="3" scalingFactor="3" />
   247  				<section zOrder="2" zPosition="5" xOffset="3" yOffset="5" scalingFactor="1" />
   248  			</xtru>`,
   249  			want: Extruded{
   250  				Name: "xtru", LUnit: "mm",
   251  				Vertices: []Vertex2D{
   252  					{XMLName: xml.Name{Local: "twoDimVertex"}, X: "3", Y: "9"},
   253  					{XMLName: xml.Name{Local: "twoDimVertex"}, X: "1", Y: "5"},
   254  					{XMLName: xml.Name{Local: "twoDimVertex"}, X: "2", Y: "4"},
   255  				},
   256  				Sections: []Section{
   257  					{XMLName: xml.Name{Local: "section"}, ZOrder: "1", ZPos: "2", XOff: "5", YOff: "3", Fact: "3"},
   258  					{XMLName: xml.Name{Local: "section"}, ZOrder: "2", ZPos: "5", XOff: "3", YOff: "5", Fact: "1"},
   259  				},
   260  			},
   261  		},
   262  		{
   263  			name: "arb8",
   264  			raw: `<arb8 name="arb8" lunit="mm"
   265  				v1x="11" v1y="12"
   266  				v2x="13" v2y="14"
   267  				v3x="15" v3y="16"
   268  				v4x="17" v4y="18"
   269  				v5x="19" v5y="20"
   270  				v6x="21" v6y="22"
   271  				v7x="23" v7y="24"
   272  				v8x="25" v8y="26"
   273  				dz="27"
   274  			/>`,
   275  			want: ArbitraryTrapezoid{
   276  				Name: "arb8", LUnit: "mm",
   277  				V1x: "11", V1y: "12",
   278  				V2x: "13", V2y: "14",
   279  				V3x: "15", V3y: "16",
   280  				V4x: "17", V4y: "18",
   281  				V5x: "19", V5y: "20",
   282  				V6x: "21", V6y: "22",
   283  				V7x: "23", V7y: "24",
   284  				V8x: "25", V8y: "26",
   285  				Dz: "27",
   286  			},
   287  		},
   288  		{
   289  			name: "tesselated",
   290  			raw: `<tesselated name="pyramid">
   291  				<triangular vertex1="v1" vertex2="v2" vertex3="v6" type="ABSOLUTE" />
   292  				<triangular vertex1="v2" vertex2="v3" vertex3="v6" type="ABSOLUTE" />
   293  				<triangular vertex1="v3" vertex2="v4" vertex3="v5" type="ABSOLUTE" />
   294  				<triangular vertex1="v4" vertex2="v1" vertex3="v5" type="ABSOLUTE" />
   295  				<triangular vertex1="v1" vertex2="v6" vertex3="v5" type="ABSOLUTE" />
   296  				<triangular vertex1="v6" vertex2="v3" vertex3="v5" type="ABSOLUTE" />
   297  				<quadrangular vertex1="v4" vertex2="v3" vertex3="v2" vertex4="v1" type="ABSOLUTE" />
   298  			</tesselated>`,
   299  			want: Tesselated{
   300  				Name: "pyramid",
   301  				Tris: []Triangular{
   302  					{XMLName: xml.Name{Local: "triangular"}, Vtx1: "v1", Vtx2: "v2", Vtx3: "v6", Type: "ABSOLUTE"},
   303  					{XMLName: xml.Name{Local: "triangular"}, Vtx1: "v2", Vtx2: "v3", Vtx3: "v6", Type: "ABSOLUTE"},
   304  					{XMLName: xml.Name{Local: "triangular"}, Vtx1: "v3", Vtx2: "v4", Vtx3: "v5", Type: "ABSOLUTE"},
   305  					{XMLName: xml.Name{Local: "triangular"}, Vtx1: "v4", Vtx2: "v1", Vtx3: "v5", Type: "ABSOLUTE"},
   306  					{XMLName: xml.Name{Local: "triangular"}, Vtx1: "v1", Vtx2: "v6", Vtx3: "v5", Type: "ABSOLUTE"},
   307  					{XMLName: xml.Name{Local: "triangular"}, Vtx1: "v6", Vtx2: "v3", Vtx3: "v5", Type: "ABSOLUTE"},
   308  				},
   309  				Quads: []Quadrangular{
   310  					{XMLName: xml.Name{Local: "quadrangular"}, Vtx1: "v4", Vtx2: "v3", Vtx3: "v2", Vtx4: "v1", Type: "ABSOLUTE"},
   311  				},
   312  			},
   313  		},
   314  		{
   315  			name: "tetrahedron",
   316  			raw:  `<tet name="halfpyramid" vertex1="v1" vertex2="v2" vertex3="v3" vertex4="v4" />`,
   317  			want: TetraHedron{
   318  				Name: "halfpyramid",
   319  				Vtx1: "v1", Vtx2: "v2", Vtx3: "v3", Vtx4: "v4",
   320  			},
   321  		},
   322  		{
   323  			name: "scaled-tube",
   324  			raw: `<scaledSolid name="scaled-tube">
   325  				<solidref ref="my-tube"/>
   326  				<scale name="tube_scale" x="1" y="2" z="3"/>
   327  			</scaledSolid>`,
   328  			want: ScaledSolid{
   329  				Name:  "scaled-tube",
   330  				Ref:   SolidRef{XMLName: xml.Name{Local: "solidref"}, Ref: "my-tube"},
   331  				Scale: Scale{Name: "tube_scale", X: "1", Y: "2", Z: "3"},
   332  			},
   333  		},
   334  	} {
   335  		t.Run(tc.name, func(t *testing.T) {
   336  			var v1 = reflect.New(reflect.TypeOf(tc.want)).Elem()
   337  			err := xml.NewDecoder(bytes.NewReader([]byte(tc.raw))).Decode(v1.Addr().Interface())
   338  			if err != nil {
   339  				t.Fatal(err)
   340  			}
   341  
   342  			want := reflect.New(reflect.TypeOf(tc.want)).Elem()
   343  			want.Set(reflect.ValueOf(tc.want))
   344  			field := want.FieldByName("XMLName")
   345  			if field != (reflect.Value{}) {
   346  				field.Set(v1.FieldByName("XMLName"))
   347  			}
   348  			if !reflect.DeepEqual(v1.Interface(), want.Interface()) {
   349  				t.Fatalf("error:\ngot = %#v\nwant= %#v", v1.Interface(), want.Interface())
   350  			}
   351  
   352  			out := new(bytes.Buffer)
   353  			err = xml.NewEncoder(out).Encode(v1.Interface())
   354  			if err != nil {
   355  				t.Fatal(err)
   356  			}
   357  
   358  			raw := out.String()
   359  			var v2 = reflect.New(reflect.TypeOf(tc.want)).Elem()
   360  			err = xml.NewDecoder(bytes.NewReader([]byte(raw))).Decode(v2.Addr().Interface())
   361  			if err != nil {
   362  				t.Fatal(err)
   363  			}
   364  
   365  			if !reflect.DeepEqual(v2.Interface(), want.Interface()) {
   366  				t.Fatalf("error:\ngot = %#v\nwant= %#v", v2.Interface(), want.Interface())
   367  			}
   368  		})
   369  	}
   370  }