Ticket #9770: IDF_to_PLY_v2.py

File IDF_to_PLY_v2.py, 5.6 KB (added by Anders Markvardsen, 6 years ago)

updated version of IDF_to_PLY.py

Line 
1from mantid.kernel import *
2from mantid.api import *
3
4# Author: E. Farhi  <farhi@ill.fr>
5# Date:   June 19th 2014
6# Description: IDF to PLY/OFF converter
7 
8class IDF_to_PLY(PythonAlgorithm):
9
10    def category(self):
11        return 'Utilities'
12
13    def PyInit(self):
14        # Declare properties
15        self.declareProperty(FileProperty(name="InputFile",defaultValue="",
16                                action=FileAction.Load, extensions = ["xml","hdf","nxs"]), 
17                                doc="An input file with associated instrument definition (IDF/XML in MANTIDPATH/instrument, NeXus or HDF)")
18       
19        # output direction specified explicitly
20        self.declareProperty(FileProperty(name="OutputFile",defaultValue="instrument_Description",
21                                action=FileAction.Save, extensions = ["off","ply"]), 
22            doc="The output file name where the geometry will be saved")
23
24        # the type of Data File generated
25        self.declareProperty("OutputFormat","OFF", StringListValidator(["OFF","PLY"]))
26
27    def PyExec(self):
28        # Run the algorithm
29
30        # Load the Instrument Definition File (IDF) e.g. XML or from NXS
31        ws = Load(Filename=self.getPropertyValue("InputFile"))
32       
33        inst  = ws.getInstrument()
34       
35        nhist = ws.getNumberHistograms()
36
37        self.log().information( "IDF_to_PLY: Opening instrument " + inst.getName() + " definition from file " + self.getPropertyValue("InputFile") + " with " + str(nhist) + " pixels.")
38
39        name = self.getPropertyValue("OutputFile")
40        fid = open(name, "w")
41
42        self.log().information( "IDF_to_PLY: Generating output file " + self.getPropertyValue("OutputFile") )
43
44        # Mantid::Geometry::OCGeometryGenerator
45        # methods: getNumberOfPoints, getNumberOfTriangles, getTriangleFaces, getTriangleVertices
46
47        nb_vertices = 0
48        nb_polygons = 0
49        vout = ""
50        pout = ""
51
52        # traverse all detector pixels
53        for i in range(nhist):
54            det = ws.getDetector(i);
55            if not det.isMonitor():
56              # det.getPos() is the position of the detector object, whatever be its internal shape and definition of origin
57              # we thus prefer to use the shape and its bounding box
58
59                BBox = det.shape().getBoundingBox() # use .centrePoint() and .width() which are V3D objects
60                # create a cuboid from the boundingBox. centerPoint is really at the center of the max-min
61                # so we add the +/- width/2
62                pos = BBox.centrePoint() -  inst.getSample().getPos()     # shift from sample
63                x0 = pos.X()
64                y0 = pos.Y()
65                z0 = pos.Z()
66                dx = BBox.width().X()/2.0
67                dy = BBox.width().Y()/2.0
68                dz = BBox.width().Z()/2.0
69
70                i = nb_vertices   # offset for vertices index
71
72                # write the X Y Z coordinate of Detector BBox position wrt sample
73                vout += '%g %g %g\n' % (x0+dx, y0-dy, z0-dz)
74                vout += '%g %g %g\n' % (x0-dx, y0+dy, z0-dz)
75                vout += '%g %g %g\n' % (x0-dx, y0-dy, z0+dz)
76                vout += '%g %g %g\n' % (x0-dx, y0-dy, z0-dz)
77                vout += '%g %g %g\n' % (x0+dx, y0-dy, z0+dz)
78                vout += '%g %g %g\n' % (x0+dx, y0+dy, z0-dz)
79                vout += '%g %g %g\n' % (x0+dx, y0+dy, z0+dz)
80                vout += '%g %g %g\n' % (x0-dx, y0+dy, z0+dz)
81                nb_vertices += 8
82
83                # write the connections after the vertices
84                pout += '%i %i %i %i %i\n' % (4, 0+i, 5+i, 6+i, 4+i)
85                pout += '%i %i %i %i %i\n' % (4, 1+i, 5+i, 6+i, 7+i)
86                pout += '%i %i %i %i %i\n' % (4, 2+i, 4+i, 6+i, 7+i)
87                pout += '%i %i %i %i %i\n' % (4, 3+i, 0+i, 4+i, 2+i)
88                pout += '%i %i %i %i %i\n' % (4, 3+i, 0+i, 5+i, 1+i)
89                pout += '%i %i %i %i %i\n' % (4, 3+i, 1+i, 7+i, 2+i)
90                nb_polygons += 6
91
92        # get the file type to export, write the file content
93        if self.getPropertyValue("InputFile") == 'OFF':
94            fid.write("OFF\n")  # 1st line, mandatory
95            fid.write("# This is an Object File Format (geomview). Use e.g. Meshlab to view it.\n")
96            fid.write("# nb points, nb faces, void\n")
97            fid.write("# List point coordinates\n")
98            fid.write("%i %i 0\n" % (nb_vertices,nb_polygons))       # nb points, nb faces, void
99            fid.write(vout)
100            fid.write("# List faces, all rectangular\n")
101            fid.write(pout)
102        else:
103            fid.write("ply\n")
104            fid.write("format ascii 1.0\n")
105            fid.write("comment " + inst.getName() + " geometry (Mantid IDF) from file " + self.getPropertyValue("InputFile") + "\n")
106            fid.write("comment This is an PLY File Format. Use e.g. Meshlab to view it.\n")
107            fid.write("element vertex %i\n" % (nb_vertices))
108            fid.write("property float32 x\n")
109            fid.write("property float32 y\n")
110            fid.write("property float32 z\n")
111            fid.write("element face %i\n" % (nb_polygons))
112            fid.write("property list uint8 int32 vertex_indices\n")
113            fid.write("end_header\n")
114            fid.write(vout)
115            fid.write(pout)
116             
117        self.log().information( "IDF_to_PLY: " + inst.getName() + " written to " + self.getPropertyValue("OutputFile") + " with %i vertices and %i polygons" % (nb_vertices, nb_polygons) )
118        #deleteWorkspace(ws)
119        # The above line deletes is supposed to delete the workspace, however causes the Algorithm to crash, so it has been commented out.
120       
121# Register algorithm with Mantid
122AlgorithmFactory.subscribe(IDF_to_PLY)