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 }