Print

Print


Author: [log in to unmask]
Date: Mon Nov 21 10:33:54 2016
New Revision: 4573

Log:
Code to convert TOSCA magnetic field map calculations into format usable by slic and hps-java

Added:
    java/trunk/util/src/main/java/org/hps/util/UnfoldFieldmap.java

Added: java/trunk/util/src/main/java/org/hps/util/UnfoldFieldmap.java
 =============================================================================
--- java/trunk/util/src/main/java/org/hps/util/UnfoldFieldmap.java	(added)
+++ java/trunk/util/src/main/java/org/hps/util/UnfoldFieldmap.java	Mon Nov 21 10:33:54 2016
@@ -0,0 +1,295 @@
+package org.hps.util;
+
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import static java.lang.Math.sqrt;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import static java.lang.Math.abs;
+
+/**
+ *
+ * @author Norman A Graf
+ *
+ */
+public class UnfoldFieldmap
+{
+
+// Storage space for the table
+    private double[][][] _xField;
+    private double[][][] _yField;
+    private double[][][] _zField;
+    // The dimensions of the table
+    private int _nx, _ny, _nz;
+    // The physical limits of the defined region
+    private double _minx, _maxx, _miny, _maxy, _minz, _maxz;
+    // The physical extent of the defined region
+    private double _dx, _dy, _dz;
+    // Offsets if field map is not in global coordinates
+    private double _xOffset;
+    private double _yOffset;
+    private double _zOffset;
+    // normalizations for the GUI
+//    double[] _maxDim = new double[3];
+//    double[] _offSet = new double[3];
+//    double _maxScale = 0.;
+    // maximum field strength
+    private double _bMax;
+    List<double[]> lines = new ArrayList<double[]>();
+    double[][] Bx;
+    double[][] By;
+    double[][] Bz;
+    double[] xVals;
+    double[] zVals;
+    double[] yVals;
+
+    private double _scaleFactor;
+    private String _map2read;
+
+    public UnfoldFieldmap()
+    {
+      _scaleFactor = 1.;
+    }
+    public UnfoldFieldmap(String map2read,double scaleFactor)
+    {
+      _map2read = map2read;
+      _scaleFactor = scaleFactor;
+    }
+    void setup()
+    {
+//        System.out.println(this.getClass().getClassLoader().getResource(map2read));
+//        InputStream is = this.getClass().getClassLoader().getResourceAsStream(map2read);
+        
+        System.out.println("\n-----------------------------------------------------------"
+                + "\n      Reading Magnetic Field map "+_map2read
+                + "\n      Scaling values by "+_scaleFactor
+                + "\n-----------------------------------------------------------");
+
+        try {
+            FileInputStream fin = new FileInputStream(_map2read);
+            BufferedReader myInput = new BufferedReader(new InputStreamReader(new BufferedInputStream(fin)));
+
+            String thisLine;
+            // ignore the first blank line
+            //thisLine = myInput.readLine();
+            // next line has table dimensions
+            thisLine = myInput.readLine();
+            System.out.println(thisLine);
+            // read in the table dimensions of the file
+            StringTokenizer st = new StringTokenizer(thisLine, " ");
+            _nx = Integer.parseInt(st.nextToken());
+            _ny = Integer.parseInt(st.nextToken());
+            _nz = Integer.parseInt(st.nextToken());
+
+            Bx = new double[_nx][_nz];
+            By = new double[_nx][_nz];
+            Bz = new double[_nx][_nz];
+            xVals = new double[_nx];
+            yVals = new double[_ny];
+            zVals = new double[_nz];
+            // Set up storage space for table
+            _xField = new double[_nx + 1][_ny + 1][_nz + 1];
+            _yField = new double[_nx + 1][_ny + 1][_nz + 1];
+            _zField = new double[_nx + 1][_ny + 1][_nz + 1];
+
+            // Ignore other header information    
+            // The first line whose second character is '0' is considered to
+            // be the last line of the header.
+            do {
+                thisLine = myInput.readLine();
+                st = new StringTokenizer(thisLine, " ");
+            } while (!st.nextToken().trim().equals("0"));
+
+            // now ready to read in the values in the table
+            // format is:
+            // x y z Bx By Bz
+            //
+            // TOSCA files have distance measured in cm
+            // TOSCA files have field in OERSTED 
+            // Geant4 requires mm and .0001T, so need to convert
+            // OERSTED to Tesla = 10000
+            // Tesla to Geant4 internal units where 1 Tesla is equal to 0.001
+            // field conversion factor is 10000000
+            //
+            double fieldConversionFactor = 10000000.;
+            double lengthConversionFactor = 10.;
+            int ix, iy, iz;
+            double xval = 0.;
+            double yval = 0.;
+            double zval = 0.;
+            double bx, by, bz;
+            for (ix = 0; ix < _nx; ix++) {
+                for (iy = 0; iy < _ny; iy++) {
+                    for (iz = 0; iz < _nz; iz++) {
+                        thisLine = myInput.readLine();
+                        st = new StringTokenizer(thisLine, " ");
+                        xval = Double.parseDouble(st.nextToken());
+                        yval = Double.parseDouble(st.nextToken());
+                        zval = Double.parseDouble(st.nextToken());
+                        bx = Double.parseDouble(st.nextToken());
+                        by = Double.parseDouble(st.nextToken());
+                        bz = Double.parseDouble(st.nextToken());
+                        double[] line = {xval, yval, zval, bx, by, bz};
+                        lines.add(line);
+                        Bx[ix][iz] = _scaleFactor*bx/fieldConversionFactor; // convert to magnetic field units used by Geant4
+                        By[ix][iz] = _scaleFactor*by/fieldConversionFactor; //
+                        Bz[ix][iz] = _scaleFactor*bz/fieldConversionFactor; //
+                        xVals[ix] = xval*lengthConversionFactor;
+                        yVals[iy] = yval*lengthConversionFactor;
+                        zVals[iz] = zval*lengthConversionFactor;
+                        if (ix == 0 && iy == 0 && iz == 0) {
+                            _minx = xval;
+                            _miny = yval;
+                            _minz = zval;
+                        }
+                        _xField[ix][iy][iz] = bx;
+                        _yField[ix][iy][iz] = by;
+                        _zField[ix][iy][iz] = bz;
+                        double b = bx * bx + by * by + bz * bz;
+                        if (b > _bMax) {
+                            _bMax = b;
+                        }
+                    }
+                }
+            }
+            _bMax = sqrt(_bMax);
+
+            _maxx = xval;
+            _maxy = yval;
+            _maxz = zval;
+
+            System.out.println("\n ---> ... done reading ");
+            System.out.println(" ---> assumed the order:  x, y, z, Bx, By, Bz "
+                    + "\n ---> Min values x,y,z: "
+                    + _minx + " " + _miny + " " + _minz + " cm "
+                    + "\n ---> Max values x,y,z: "
+                    + _maxx + " " + _maxy + " " + _maxz + " cm "
+                    + "\n Maximum Field strength: " + _bMax + " "
+                    + "\n ---> The field will be offset by " + _xOffset + " " + _yOffset + " " + _zOffset + " cm ");
+
+            _dx = _maxx - _minx;
+            _dy = _maxy - _miny;
+            _dz = _maxz - _minz;
+            System.out.println("\n ---> Range of values x,y,z: "
+                    + _dx + " " + _dy + " " + _dz + " cm in z "
+                    + "\n-----------------------------------------------------------");
+
+            System.out.println(lines.size());
+            myInput.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        // want to normalize the dimensions to fit into the visible 1x1x1 cube of the applet
+//        _maxDim[0] = (_maxx - _minx) / 2.;
+//        _maxDim[1] = (_maxy - _miny) / 2.;
+//        _maxDim[2] = (_maxz - _minz) / 2.;
+//        for (int ii = 0; ii < 3; ++ii) {
+//            if (_maxDim[ii] > _maxScale) {
+//                _maxScale = _maxDim[ii];
+//            }
+//        }
+//        _offSet[0] = (_maxx + _minx) / 2.;
+//        _offSet[1] = (_maxy + _miny) / 2.;
+//        _offSet[2] = (_maxz + _minz) / 2.;
+
+    }
+
+    public void writeout()
+    {
+        try {
+            // output : Unicode to Cp850 (MS-DOS Latin-1)
+            FileOutputStream fos = new FileOutputStream("out.dat");
+            Writer w =
+                    new BufferedWriter(new OutputStreamWriter(fos, "Cp850"));
+            w.write("\n");
+            w.write((2 * _nx - 1) + " " + (2 * _ny - 1) + " " + (2 * _nz - 1)+"\n");
+            w.write(" 1 X(mm) \n");
+            w.write(" 2 Y(mm) \n");
+            w.write(" 3 Z(mm) \n");
+            w.write(" 4 BX(1000T) \n");
+            w.write(" 5 BY(1000T) \n");
+            w.write(" 6 BZ(1000T) \n");
+            w.write(" 0 End of Header. Data follows in above format \n");
+
+            // want to reflect the field in x and z
+            // for now, assume (0,0) is minimum for (x,z)
+            
+            for (int i = -(_nx - 1); i < _nx; ++i) {
+                for (int j = -(_ny - 1); j < _ny; ++j) {
+                    for (int k = -(_nz - 1); k < _nz; ++k) {
+                        double xSign = (i < 0) ? -1. : 1.;
+                        double ySign = (j < 0) ? -1. : 1.;
+                        double zSign = (k < 0) ? -1. : 1.;
+//                        double x = (i < 0) ? -xVals[abs(i)] : xVals[abs(i)];
+//                        double y = (j < 0) ? -yVals[abs(j)] : yVals[abs(j)];
+//                        double z = (k < 0) ? -zVals[abs(k)] : zVals[abs(k)];
+                        w.write(xSign*xVals[abs(i)] + " " + ySign*yVals[abs(j)] + " " + zSign*zVals[abs(k)] +" "+ xSign*Bx[abs(i)][abs(k)]+" " + By[abs(i)][abs(k)] + " "+zSign*Bz[abs(i)][abs(k)] + " \n");
+                    }
+                }
+            }
+
+            w.flush();
+            w.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+    }
+    
+//    public void writeoutGnuplot()
+//    {
+//        try {
+//            // output : Unicode to Cp850 (MS-DOS Latin-1)
+//            FileOutputStream fos = new FileOutputStream("gnuplot.dat");
+//            Writer w =
+//                    new BufferedWriter(new OutputStreamWriter(fos, "Cp850"));
+//            // want to reflect the field in x and z
+//            // for now, assume (0,0) is minimum for (x,z)
+//            for (int i = -(_nx - 1); i < _nx; ++i) {
+//                //for (int j = 0; j < _ny; ++j) {
+//                    for (int k = -(_nz - 1); k < _nz; ++k) {
+//                        double x = (i < 0) ? -xVals[abs(i)] : xVals[abs(i)];
+//                        double z = (k < 0) ? -zVals[abs(k)] : zVals[abs(k)];
+//                        w.write(x + " " + z + " " + By[abs(i)][abs(k)] + "\n");
+//                    }
+//                    w.write("\n");
+//                //}
+//            }
+//
+//            w.flush();
+//            w.close();
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }    
+
+    public static void main(String[] args)
+    {
+        String map2read = "209acm2_5kg.table";
+        double scaleFactor = 1.0;
+        if(args.length>0) 
+        {
+          map2read = args[0];
+        }
+        if(args.length>1) 
+        {
+          scaleFactor = Double.parseDouble(args[1]);
+        }
+        System.out.println("Reading in field map "+map2read);
+        System.out.println("Scaling field map by "+scaleFactor);
+        UnfoldFieldmap doit = new UnfoldFieldmap(map2read,scaleFactor);
+        doit.setup();
+        doit.writeout();
+//        doit.writeoutGnuplot();
+    }
+}
+