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(); + } +} +