lcsim/src/org/lcsim/contrib/NickSinev/PixSim
diff -u -r1.1 -r1.2
--- TCADFieldMap.java 1 Jul 2008 21:40:04 -0000 1.1
+++ TCADFieldMap.java 26 Jul 2008 01:30:07 -0000 1.2
@@ -10,7 +10,7 @@
import hep.physics.vec.VecOp;
/**
- * Field map read from TCAD simulation output
+ * Facility to read electric field map from TCAD simulation output
* @author Nick Sinev
*/
@@ -21,7 +21,7 @@
static final double tcad_fldunit = 0.1;
public enum WeightFunction {POWER4,POWER6,POWER8,EXPONENT,SOFTEXP,HARDEXP};
private WeightFunction wfunc = WeightFunction.EXPONENT;
- String name;
+ String name = "Undefined";
ITransform3D sens_tcadcst = new Transform3D();
boolean use_tcad_map = false;
boolean do_interp = true;
@@ -42,6 +42,12 @@
double xran = 0.;
double yran = 0.;
double zran = 0.;
+ double xmin = -4.*micron;
+ double ymin = -4.*micron;
+ double zmin = 0.;
+ double xmax = 4.*micron;
+ double ymax = 4.*micron;
+ double zmax = 20.*micron;
int gpnx = 0;
int gpny = 0;
int gpnz = 0;
@@ -59,42 +65,88 @@
boolean tcad_map_read = false;
double[] tf = new double[3];
List<String> regions = new ArrayList<String>();
+ int dbg_lvl=0;
+/**
+* Default constractor. Creates TCADFieldMap object with field name "Undefined"
+*
+*/
+ public TCADFieldMap()
+ {
+ }
+/**
+* Constractor,which creates TCADFieldMap object with given field name
+* @param nam <code>String</code> name of this field
+*/
public TCADFieldMap(String nam)
{
name=nam;
}
+/**
+* setting debug level. if it 0 - no info prints
+* @param lvl <code>int</code> - desired debug level
+*/
+
+ public void setDebugLevel(int lvl) { dbg_lvl=lvl; }
+
+/**
+* Weight function chooser.
+* Weight function defines how 3D interpolation will weight
+* contributions from grid points depending on the distance from
+* the requested point. It is enumerated in the public enumeration WeightFunction
+* defined in this class: POWER4,POWER6,POWER8,EXPONENT,SOFTEXP,HARDEXP
+* From my point of view best results gives EXPONENT
+* @param wf <code>enumeration</code> of 6 predefined weight functions and should be
+* given like this: setWeightFunction(TCADFieldMap.WeightFunction.POWER4)
+* If you want to use exponent, you don't need to call this setter, as
+* EXPONENT is default option
+*/
public void setWeightFunction(WeightFunction wf)
{
wfunc=wf;
}
- /**
- * Set whether to use direct TCAD map (opposit to usage of transformed map).
- * @param yes if true, TCAD map read from TCAD output, with irregular mesh points will be used
- * for calculating field value. This can take thousands times longer than usage of field map on
- * regular rectangular grid
- */
-
+/**
+* Set whether to use direct TCAD map (opposit to usage of transformed map).
+* @param yes <code>boolean</code> if true, TCAD map read from TCAD output,
+* with irregular mesh points will be used for calculating field value.
+* This can take thousands times longer than usage of field map on
+* regular rectangular grid. But this setting makes sense, when we need
+* only few hundreds or thousands of field readings (for example, just
+* to have look at the field), because building of transformed map
+* takes pretty long time.
+*/
public void setUseTCADMap( boolean yes)
{
use_tcad_map=yes;
}
-
+/**
+* Set wether to do interpolation for field value.
+* @param yes - <code>boolean</code> flag. If this flag set to false, the returned field value
+* will be taken directly from nearest grid point. In that case field as function
+* of coordinates will not be a smooth function.
+*
+*/
public void setDoInterpolation( boolean yes)
{
do_interp=yes;
}
- public void setMapDimensions(double mdx,double mdy, double mdz)
- {
- fdimx = mdx;
- fdimy = mdy;
- fdimz = mdz;
- }
-
+/**
+* Setting grid steps for ortogonal grid. This steps will be used to
+* convert from TCAD map with irregular point positions to map on the
+* regular grid, which can be saved and used in future. Saving map on regular
+* grid makes interpolation of the field in between grid points much,much faster
+* (may be thousands time faster), when interpolation between direct reedings
+* from TCAD file. These steps are recorded in the header of field map file saved,
+* so when one read such file back, there is no need to set them - they will
+* be restored from file. By default they are set to 0.2 microns in either direction.
+* @param gsx - grid step in x
+* @param gsy - grid step in y
+* @param gsz - grid step in z
+*/
public void setGrid(double gsx, double gsy, double gsz)
{
grdstx = gsx;
@@ -102,175 +154,244 @@
grdstz = gsz;
}
- public boolean readMap(String mfnam, String dfnam, ITransform3D cstrans) throws IOException
- {
- sens_tcadcst = cstrans;
- return readMap(mfnam,dfnam);
- }
-
- public boolean readMap(String mfnam, String dfnam, String onam, ITransform3D cstrans) throws IOException
+/**
+* Setting the limits for saving field in regular grid file.
+* Field from TCAD file may be defined on larger region.
+* But for pixel simulation we need only field inside one pixel,
+* and it is assumed that it is the same if we translate coordinates
+* by pixel size. So, to save memory and file size, this dimensions
+* should be set according to pixel size.
+* @param mdx <code>double</code> - limits in x direction are set: minx=-mdx/2 maxx=+mdx/2
+* @param mdy <code>double</code> - limits in y direction are set: miny=-mdy/2 maxy=+mdy/2
+* @param mdz <code>double</code> - limits in z direction are set: minz=0.0 maxz=+mdz
+*
+*/
+ public void setMapDimensions(double mdx,double mdy, double mdz)
{
- sens_tcadcst = cstrans;
- return readMap(mfnam,dfnam,onam);
+ fdimx = mdx;
+ fdimy = mdy;
+ fdimz = mdz;
}
-
+/**
+* Read back limits of area where field was defined
+* (useful after reading map with unknown limits)
+* Returns spatial limits of mapped area in the form
+* of 6-dimensional double array:
+* xmin,xmax,ymin,ymax,zmin,zmax
+* @return <code>double[]</code> array of map limits
+*
+*/
+ public double[] getMapLimits()
+ {
+ double[] limits = new double[6];
+ limits[0]=xmin;
+ limits[1]=xmax;
+ limits[2]=ymin;
+ limits[3]=ymax;
+ limits[4]=zmin;
+ limits[5]=zmax;
+ return limits;
+ }
+
+/**
+* Function readMap is overloaded - depending on number and types of its
+* arguments it performs different actions. In the case of single String argument
+* this function reads field map in the form of the map on the regular rectangular grid.
+* Such file is generated and saved as result of readMap function with different number
+* of arguments - see below.
+* @param mfnam <code>String</code> - name of field map file. If this is not a complete path,
+* it will be searched in user cashe directory
+* @return <code>boolean</code> - true if file was found and read, false if file was not found
+* or has wrong format
+*/
public boolean readMap(String mfnam) throws IOException
{
- String cacheDir = System.getProperty("user.home");
- File cachedir = new File(cacheDir);
-
- if(cachedir == null)
+ use_tcad_map=false; // When reading map in regular rectangular form, we do not have TCAD row map available
+ File cache = new File(mfnam);
+ if(!cache.exists())
{
- System.out.println("TCADFieldMap is unable to find user home directory!");
+ String cacheDir = System.getProperty("user.home");
+ File cachedir = new File(cacheDir);
+ if(cachedir == null)
+ {
+ System.out.println("TCADFieldMap is unable to find user home directory!");
+ }
+ else
+ {
+ File home = new File(cachedir,".cache");
+ cache = new File(home,mfnam);
+ }
}
- else
+ if(cache.exists())
{
- File home = new File(cachedir,".cache");
- File cache = new File(home,mfnam);
- if(cache.exists())
+ String rstr=null;
+ BufferedReader r=null;
+ if(dbg_lvl > 0) System.out.println("Found field map file "+cache.getAbsolutePath());
+ FileInputStream fins = null;
+ try
{
- String rstr=null;
- BufferedReader r=null;
- System.out.println("Found field map file "+cache.getAbsolutePath());
- FileInputStream fins = null;
- try
- {
- fins = new FileInputStream(cache);
- }
- catch(FileNotFoundException e)
+ fins = new FileInputStream(cache);
+ }
+ catch(FileNotFoundException e)
+ {
+ }
+ finally
+ {
+ }
+ if(fins != null)
+ {
+ r = new BufferedReader(new InputStreamReader(fins));
+ if((rstr = freader.readNextNonCommentLine(r)) != null)
{
+ String[] tokens = rstr.split("\\s+");
+ int ntp = tokens.length;
+ if(ntp < 3)
+ {
+ System.out.println("Error in table header. Number of grid indexes less than 3");
+ map_read=false;
+ return map_read;
+ }
+ int[] tpar = new int[ntp];
+ int np=0;
+ for(int i=0; i<ntp; i++)
+ {
+ try
+ {
+ int ival = Integer.parseInt(tokens[i]);
+ tpar[np]=ival;
+ np++;
+ }
+ catch(NumberFormatException e)
+ {
+ System.out.println("Error in table header - integer values are not integer");
+ map_read=false;
+ return map_read;
+ }
+ finally
+ {
+ }
+ }
+ gpnx=tpar[0];
+ gpny=tpar[1];
+ gpnz=tpar[2];
+ int tnsmp=gpnx*gpny*gpnz;
+ if(dbg_lvl > 0) System.out.println(
+ "Table made from "+tnsmp+" samples = "+gpnx+" x "+gpny+" x "+gpnz+" space pnts");
}
- finally
+ gfldx = new double[gpnx][gpny][gpnz];
+ gfldy = new double[gpnx][gpny][gpnz];
+ gfldz = new double[gpnx][gpny][gpnz];
+ if((rstr = freader.readNextNonCommentLine(r)) != null)
{
- }
- if(fins != null)
- {
- r = new BufferedReader(new InputStreamReader(fins));
- if((rstr = freader.readNextNonCommentLine(r)) != null)
+ String[] tokens = rstr.split("\\s+");
+ int ntp = tokens.length;
+ if(ntp < 6)
+ {
+ System.out.println("Error in table header. Number of recorded limits < 6");
+ map_read = false;
+ return map_read;
+ }
+ double[] tpar = new double[ntp];
+ int np=0;
+ for(int i=0; i<ntp; i++)
{
- String[] tokens = rstr.split("\\s+");
- int ntp = tokens.length;
- if(ntp < 3) System.out.println("Error in table header");
- int[] tpar = new int[ntp];
- int np=0;
- for(int i=0; i<ntp; i++)
+ try
+ {
+ double dval = Double.parseDouble(tokens[i]);
+ tpar[np]=dval;
+ np++;
+ }
+ catch(NumberFormatException e)
+ {
+ System.out.println("Error in table header - wrong format for limits");
+ map_read=false;
+ return map_read;
+ }
+ finally
{
- try
- {
- int ival = Integer.parseInt(tokens[i]);
- tpar[np]=ival;
- np++;
- }
- catch(NumberFormatException e)
- {
- }
- finally
- {
- }
}
- gpnx=tpar[0];
- gpny=tpar[1];
- gpnz=tpar[2];
- int tnsmp=gpnx*gpny*gpnz;
- System.out.println(
- "Table made from "+tnsmp+" samples = "+gpnx+" x "+gpny+" x "+gpnz+" space pnts");
}
- gfldx = new double[gpnx][gpny][gpnz];
- gfldy = new double[gpnx][gpny][gpnz];
- gfldz = new double[gpnx][gpny][gpnz];
- if((rstr = freader.readNextNonCommentLine(r)) != null)
+ gx0=tpar[0];
+ gy0=tpar[1];
+ gz0=tpar[2];
+ grdstx=tpar[3];
+ grdsty=tpar[4];
+ grdstz=tpar[5];
+ if(dbg_lvl > 0) System.out.println("x0 "+gx0+" y0 "+gy0+" z0 "+gz0+" stx "+grdstx+" sty "+grdsty+" stz "+grdstz);
+ xmin = gx0;
+ ymin = gy0;
+ zmin = gz0;
+ xmax = xmin + grdstx*(gpnx-1);
+ ymax = ymin + grdsty*(gpny-1);
+ zmax = zmin + grdstz*(gpnz-1);
+ }
+ boolean done = false;
+ int ix=0;
+ int iy=0;
+ int iz=0;
+ int np=0;
+ while(((rstr = freader.readNextNonCommentLine(r)) != null)&& (!done))
+ {
+ String[] tokens = rstr.split("\\s+");
+ int ntp = tokens.length;
+ if(ntp < 3) System.out.println("Error in table format: expected 3 values in line, read: "+ntp);
+ np=0;
+ for(int i=0; i<ntp; i++)
{
- String[] tokens = rstr.split("\\s+");
- int ntp = tokens.length;
- if(ntp < 6) System.out.println("Error in table header");
- double[] tpar = new double[ntp];
- int np=0;
- for(int i=0; i<ntp; i++)
+ try
{
- try
+ double val = Double.parseDouble(tokens[i]);
+ if(np==0) gfldx[ix][iy][iz]=val;
+ if(np==1) gfldy[ix][iy][iz]=val;
+ if(np==2) gfldz[ix][iy][iz]=val;
+ if(np>2)
{
- double dval = Double.parseDouble(tokens[i]);
- tpar[np]=dval;
- np++;
+ System.out.println("Error in file records format: more than 3 values in one line");
+ map_read = false;
+ return map_read;
}
- catch(NumberFormatException e)
+ np++;
+ if(np>2) iz++;
+ if(iz == gpnz)
{
- }
- finally
- {
- }
- }
- gx0=tpar[0];
- gy0=tpar[1];
- gz0=tpar[2];
- grdstx=tpar[3];
- grdsty=tpar[4];
- grdstz=tpar[5];
- System.out.println("x0 "+x0+" y0 "+y0+" z0 "+z0+" stx "+grdstx+" sty "+grdsty+" stz "+grdstz);
- }
- boolean done = false;
- int ix=0;
- int iy=0;
- int iz=0;
- int np=0;
- while(((rstr = freader.readNextNonCommentLine(r)) != null)&& (!done))
- {
- String[] tokens = rstr.split("\\s+");
- int ntp = tokens.length;
- if(ntp < 3) System.out.println("Error in table format: expected 3 values in line, read: "+ntp);
- np=0;
- for(int i=0; i<ntp; i++)
- {
- try
- {
- double val = Double.parseDouble(tokens[i]);
- if(np==0) gfldx[ix][iy][iz]=val;
- if(np==1) gfldy[ix][iy][iz]=val;
- if(np==2) gfldz[ix][iy][iz]=val;
- if(np>2) System.out.println("Error in file records format: more than 3 values in one line");
- np++;
- if(np>2) iz++;
- if(iz == gpnz)
+ iz=0;
+ iy++;
+ if(iy == gpny)
{
- iz=0;
- iy++;
- if(iy == gpny)
- {
- iy=0;
- ix++;
- if(ix == gpnx) { done=true; map_read=true; }
- }
- }
+ iy=0;
+ ix++;
+ if(ix == gpnx) { done=true; map_read=true; }
+ }
}
- catch(NumberFormatException e)
- {
- }
- finally
- {
- }
- } // end of for loop
- } // end of while loop
- } // end of if(fins!=null) clouse
- } // end of if(cashe.exist()) clouse
- } // end of else to cahedir == null clouse
- System.out.println("First fx values: "+gfldx[0][0][0]+" "+gfldx[0][0][1]+" "+gfldx[0][0][2]);
+ }
+ catch(NumberFormatException e)
+ {
+ System.out.println("Error in file records format: values are not double ");
+ map_read=false;
+ return map_read;
+ }
+ finally
+ {
+ }
+ } // end of for loop
+ } // end of while loop
+ } // end of if(fins!=null) clouse
+ } // end of if(cashe.exist()) clouse
+ if(dbg_lvl > 1) System.out.println("First fx values: "+gfldx[0][0][0]+" "+gfldx[0][0][1]+" "+gfldx[0][0][2]);
return map_read;
} // end of function readMap()
- public boolean readMap(String mfnam, String dfnam, String ofnam) throws IOException
- {
- boolean success = false;
- success = readMap(mfnam,dfnam);
- boolean utmsaved = use_tcad_map;
- use_tcad_map=true;
- boolean disaved = do_interp;
- do_interp=true;
- buildGrid();
- writeMap(ofnam,mfnam,dfnam);
- use_tcad_map=utmsaved;
- do_interp = disaved;
- return success;
- }
+/**
+* Function readMap with two String arguments performs reading of electric map from
+* TCAD output file. To do this it also needs another file< which contains
+* information about TCAD mesh used to create electric field data file.
+* @param mfnam <code>String</code> - name of mesh file (in TCAD such file usually
+* have names like *_msh.grd). If this is not a complete path, it will be searched in user cashe directory.
+* @param dfnam <code>String</code> - name of device simulation output file (in TCAD such file usually
+* have names like *_des.dat). If this is not a complete path, it will be searched in user cashe directory.
+* @return <code>boolean</code> - true if files were found and read, false if files were not found
+* or had wrong format
+*/
public boolean readMap(String mfnam, String dfnam) throws IOException
{
@@ -282,7 +403,7 @@
String[] regnames = null;
int[] ncinel = {1,2,3,4,-1,4,5,5,6,7,-1};
int[] rmsks={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192, 16384, 32768};
- int nvtxfldv = 0;
+// int nvtxfldv = 0;
boolean success = false;
ITransform3D tcad_senscst = sens_tcadcst.inverse();
if(name==null) name = new String(dfnam);
@@ -335,7 +456,7 @@
{
BufferedReader meshr=null;
BufferedReader datar=null;
- System.out.println("Found mesh file "+mesh.getAbsolutePath());
+ if(dbg_lvl > 0) System.out.println("Found mesh file "+mesh.getAbsolutePath());
FileInputStream finsm = null;
try
{
@@ -351,7 +472,7 @@
{
meshr = new BufferedReader(new InputStreamReader(finsm));
}
- System.out.println("Found field data file "+dfile.getAbsolutePath());
+ if(dbg_lvl > 0) System.out.println("Found field data file "+dfile.getAbsolutePath());
FileInputStream finsd = null;
try
{
@@ -367,6 +488,11 @@
{
datar = new BufferedReader(new InputStreamReader(finsd));
}
+ if((meshr == null) || (datar == null))
+ {
+ System.out.println("Unable to read TCAD field map!");
+ return false;
+ }
String rdstr = meshr.readLine();
String fld = null;
boolean ininfo = false;
@@ -400,14 +526,14 @@
{
if(ininfo)
{
- System.out.println(rdstr);
+ if(dbg_lvl > 0) System.out.println(rdstr);
if(rdstr.indexOf("nb_vertices") != -1)
{
fldst = rdstr.indexOf("=");
fldst++;
fld = rdstr.substring(fldst,rdstr.length());
nvtx = Integer.parseInt(fld.trim());
- System.out.println("Number of vertices: "+nvtx);
+ if(dbg_lvl > 0) System.out.println("Number of vertices: "+nvtx);
rdstr = meshr.readLine();
}
if(rdstr.indexOf("nb_edges") != -1)
@@ -416,7 +542,7 @@
fldst++;
fld = rdstr.substring(fldst,rdstr.length());
nedges = Integer.parseInt(fld.trim());
- System.out.println("Number of edges: "+nedges);
+ if(dbg_lvl > 0) System.out.println("Number of edges: "+nedges);
rdstr = meshr.readLine();
}
if(rdstr.indexOf("nb_faces") != -1)
@@ -425,7 +551,7 @@
fldst++;
fld = rdstr.substring(fldst,rdstr.length());
nfaces = Integer.parseInt(fld.trim());
- System.out.println("Number of faces: "+nfaces);
+ if(dbg_lvl > 0) System.out.println("Number of faces: "+nfaces);
rdstr = meshr.readLine();
}
if(rdstr.indexOf("nb_elements") != -1)
@@ -434,7 +560,7 @@
fldst++;
fld = rdstr.substring(fldst,rdstr.length());
nelems = Integer.parseInt(fld.trim());
- System.out.println("Number of elements: "+nelems);
+ if(dbg_lvl > 0) System.out.println("Number of elements: "+nelems);
rdstr = meshr.readLine();
}
if(rdstr.indexOf("nb_regions") != -1)
@@ -443,7 +569,7 @@
fldst++;
fld = rdstr.substring(fldst,rdstr.length());
nregs = Integer.parseInt(fld.trim());
- System.out.println("Number of regions: "+nregs);
+ if(dbg_lvl > 0) System.out.println("Number of regions: "+nregs);
rdstr = meshr.readLine();
}
if((rdstr.indexOf("regions") !=-1) && (rdstr.indexOf("[") !=-1))
@@ -506,7 +632,7 @@
if(rdstr.indexOf("Elements") != -1)
{
inelms=true; inelmlvl = level; nvrd=0;
-// System.out.println("Entered Elements block at level "+level);
+ if(dbg_lvl > 1) System.out.println("Entered Elements block at level "+level);
if(!inreg) { rdstr = meshr.readLine(); dcded = true;}
}
if(rdstr.indexOf("Region") !=-1)
@@ -526,7 +652,7 @@
String rname = rdstr.substring(stni,enni);
for(int i=0; i<nregs; i++)
if(regnames[i].equals(rname)) regind = i;
- System.out.println("Found region record for region "+regind+" name: "+rname+" , level "+level);
+ if(dbg_lvl > 0) System.out.println("Found region record for region "+regind+" name: "+rname+" , level "+level);
}
chind++;
} // end while
@@ -606,7 +732,7 @@
}
}
nvrd+=nnbs;
-// if(nvrd >= nelinreg) System.out.println("Processed "+nvrd+" elements in region "+regind);
+ if((nvrd >= nelinreg) && (dbg_lvl > 1)) System.out.println("Processed "+nvrd+" elements in region "+regind);
dcded = false;
} // end if(nvrd < nelinreg)
}// end if(inelms)
@@ -616,7 +742,11 @@
if(nvrd < nvtx)
{
int nnbs = getDoublesFromString(rdstr,dvals);
- if(nnbs != 3) System.out.println("Error reading vertecies - number of values in the string: "+nnbs);
+ if(nnbs != 3)
+ {
+ System.out.println("Error reading vertecies - number of values in the string: "+nnbs);
+ return false;
+ }
if(nnbs == 3)
{
mxc=micron * dvals[0];
@@ -636,7 +766,11 @@
if((inedgs) && (nvrd < nedges))
{
int nnbs = getIntegersFromString(rdstr,ivals);
- if(nnbs != 2) System.out.println("Error reading vertecies - number of values in the string: "+nnbs);
+ if(nnbs != 2)
+ {
+ System.out.println("Error reading edges - number of values in the string: "+nnbs);
+ return false;
+ }
if(nnbs == 2)
{
edgv1[nvrd]=ivals[0];
@@ -684,8 +818,11 @@
elements[nvrd]=el;
nvrd++;
}
- else System.out.println("Uncnown element type: "+etyp);
- if(nvrd == nelems) System.out.println("Recorded "+nvrd+" elements");
+ else
+ {
+ System.out.println("Unknown element type: "+etyp);
+ }
+ if((nvrd == nelems) && (dbg_lvl > 0)) System.out.println("Decoded "+nvrd+" elements");
}
dcded = false;
} // end if((inelms && !inreg) && (nvrd<nelems))
@@ -698,7 +835,7 @@
} // end if(indata)
if(!dcded)
{
-// if(rdstr.indexOf("{") !=-1) System.out.println("string "+rdstr+" is not decoded. Level is: "+level);
+ if((rdstr.indexOf("{") !=-1) && (dbg_lvl > 0)) System.out.println("string "+rdstr+" is not decoded. Level is: "+level);
if(rdstr.indexOf("}") !=-1) level--;
rdstr = meshr.readLine();
if(rdstr == null) break;
@@ -713,7 +850,7 @@
for(int j=0; j<nregs; j++) if((vmsk[i] & rmsks[j]) != 0) nvtcspre[j]++;
}
for(int i=0; i<nregs; i++)
- System.out.println("Number of verteces in region "+i+" is "+nvtcspre[i]);
+ if(dbg_lvl > 0) System.out.println("Number of verteces in region "+i+" is "+nvtcspre[i]);
RegVList[] rvlst = new RegVList[nregs];
for(int i=0; i<nregs; i++)
{
@@ -740,7 +877,7 @@
boolean strtset=false;
double[] dbuf = new double[40];
rdstr = datar.readLine();
- System.out.println("Start reading field data: "+rdstr);
+ if(dbg_lvl > 0) System.out.println("Start reading field data: "+rdstr);
int rvtin = -1;
while(rdstr != null)
{
@@ -760,7 +897,7 @@
din++;
if(din==3)
{
- if(nvrd == 0) System.out.println("First field point: "+mxc+" "+myc+" "+mzc);
+ if((nvrd == 0) && (dbg_lvl > 1)) System.out.println("First field point: "+mxc+" "+myc+" "+mzc);
tccp.setV(mxc,myc,mzc);
tcad_senscst.rotate(tccp);
if(nvrd >= rvlst[regind].vtx.length) System.out.println("RegVList for region "+regind+" has only "+rvlst[regind].vtx.length+" records");
@@ -784,7 +921,7 @@
int vind=-1;
if(!strt && strtset)
{
- System.out.println(rdstr);
+ if(dbg_lvl > 0) System.out.println(rdstr);
int bind = -1;
int cbind = -1;
if((vind = rdstr.indexOf("validity")) !=-1)
@@ -798,9 +935,9 @@
cbind = bind;
while(rdstr.charAt(cbind) != '\"') cbind++;
String snbv = rdstr.substring(bind,cbind);
- System.out.println("Searhing index for region named: "+snbv);
+ if(dbg_lvl > 1) System.out.println("Searhing index for region named: "+snbv);
for(int i=0; i < regnames.length; i++) { if(snbv.equals(regnames[i])) regind = i; }
- System.out.println("index is: "+regind);
+ if(dbg_lvl > 1) System.out.println("index is: "+regind);
nvrd = 0;
din = 0;
}
@@ -816,7 +953,7 @@
while(rdstr.charAt(bind) == ' ') bind++;
String snbv = rdstr.substring(bind,cbind);
nvval = Integer.parseInt(snbv);
- System.out.println("Number of values in e-field dataset is "+nvval);
+ if(dbg_lvl > 0) System.out.println("Number of values in e-field dataset is "+nvval);
nvpreg = nvval/3;
strt=true;
}
@@ -829,10 +966,9 @@
int bind = -1;
if((vind = rdstr.indexOf("Dataset")) !=-1)
{
-// System.out.println("Found dataset: "+rdstr);
+ if(dbg_lvl > 0) System.out.println("Found dataset: "+rdstr);
if((bind = rdstr.indexOf("ElectricField-Vector",vind)) !=-1)
{
- System.out.println("Found dataset ElectricField-Vector");
strtset=true;
strt = false;
}
@@ -841,15 +977,15 @@
} // end if((cind = rdstr.indexOf("#")) == -1) (non-comment line)
rdstr = datar.readLine();
} // end of while(rdstr != null)
- System.out.println("Data read completed file had "+nncl+" non-comment lines, and "+nvtxfldv+" vertex field data points");
+ if(dbg_lvl > 0) System.out.println("Data read completed. File had "+nncl+" non-comment lines, and "+nvtx+" vertex field data points");
} // end of if(meshfound && datafound)
success = true;
x0 = mshx[0];
y0 = mshy[0];
z0 = mshz[0];
- double xmax = x0;
- double ymax = y0;
- double zmax = z0;
+ xmax = x0;
+ ymax = y0;
+ zmax = z0;
for(int i=0; i<nvtx; i++)
{
if(mshx[i]<x0) x0=mshx[i];
@@ -859,10 +995,100 @@
if(mshy[i]>ymax) ymax=mshy[i];
if(mshz[i]>zmax) zmax=mshz[i];
}
- System.out.println("x0,y0,z0 "+x0+" "+y0+" "+z0+" xmax,ymax,zmax "+xmax+" "+ymax+" "+zmax);
+ if(dbg_lvl > 0) System.out.println("x0,y0,z0 "+x0+" "+y0+" "+z0+" xmax,ymax,zmax "+xmax+" "+ymax+" "+zmax);
+ xmin = x0;
+ ymin = y0;
+ zmin = z0;
+ if(!use_tcad_map)
+ {
+ use_tcad_map=true;
+ buildGrid();
+ use_tcad_map=false;
+ }
return success;
}
+/**
+* Function readMap with two String arguments and one Itransform3D argument
+* performs reading of electric map from TCAD output file. To do this it also
+* needs another file, which contains information about TCAD mesh used to create
+* electric field data file. Third argument sets coordinate transformation to convert
+* data recorded in TCAD coordinates into sensor coordinates.
+* @param mfnam <code>String</code> - name of mesh file (in TCAD such file usually
+* have names like *_msh.grd). If this is not a complete path, it will be searched in user cashe directory.
+* @param dfnam <code>String</code> - name of device simulation output file (in TCAD such file usually
+* have names like *_des.dat). If this is not a complete path, it will be searched in user cashe directory.
+* @param cstrans <code>ITransform3D</code> is the coordinate transformation object to transform
+* from sensor to TCAD coordinates (in reading TCAD data inverse transformation is used)
+* @return <code>boolean</code> - true if files were found and read, false if files were not found
+* or had wrong format
+*/
+ public boolean readMap(String mfnam, String dfnam, ITransform3D cstrans) throws IOException
+ {
+ sens_tcadcst = cstrans;
+ map_read = readMap(mfnam,dfnam);
+ return map_read;
+ }
+
+/**
+* Function readMap with 3 String arguments and one Itransform3D argument
+* performs reading of electric map from TCAD output file and saves it into
+* file with regular grid. To do this it also needs another file, which contains information
+* about TCAD mesh used to create electric field data file. Third argument sets the name for
+* the output file, which will contain map on regular grid. The fourth argument defines coordinate
+* transformation to convert data recorded in TCAD coordinates into sensor coordinates.
+* @param mfnam <code>String</code> - name of mesh file (in TCAD such file usually
+* have names like *_msh.grd). If this is not a complete path, it will be searched in user cashe directory.
+* @param dfnam <code>String</code> - name of device simulation output file (in TCAD such file usually
+* have names like *_des.dat). If this is not a complete path, it will be searched in user cashe directory.
+* @param onam <code>String</code> - name of the output file to which regular field map will be
+* recorded. If this is not a complete path, it will be saved in user cashe directory.
+* @param cstrans <code>ITransform3D</code> is the coordinate transformation object to transform
+* from sensor to TCAD coordinates (in reading TCAD data inverse transformation is used)
+* @return <code>boolean</code> - true if files were found and read, false if files were not found
+* or had wrong format
+*/
+ public boolean readMap(String mfnam, String dfnam, String onam, ITransform3D cstrans) throws IOException
+ {
+ sens_tcadcst = cstrans;
+ map_read = readMap(mfnam,dfnam,onam);
+ return map_read;
+ }
+
+/**
+* Function readMap with 3 String arguments performs reading of electric map from TCAD output
+* file and saves it into file with regular grid. To do this it also needs another file, which
+* contains information about TCAD mesh used to create electric field data file. Third argument sets the name for
+* the output file, which will contain map on regular grid. Coordinate transformation is assumed to be set
+* before this call.
+* @param mfnam <code>String</code> - name of mesh file (in TCAD such file usually
+* have names like *_msh.grd). If this is not a complete path, it will be searched in user cashe directory.
+* @param dfnam <code>String</code> - name of device simulation output file (in TCAD such file usually
+* have names like *_des.dat). If this is not a complete path, it will be searched in user cashe directory.
+* @param onam <code>String</code> - name of the output file to which regular field map will be
+* recorded. If this is not a complete path, it will be saved in user cashe directory.
+* @return <code>boolean</code> - true if files were found and read, false if files were not found
+* or had wrong format
+*/
+ public boolean readMap(String mfnam, String dfnam, String ofnam) throws IOException
+ {
+ boolean success = false;
+ success = readMap(mfnam,dfnam);
+ boolean utmsaved = use_tcad_map;
+ boolean disaved = do_interp;
+ if(use_tcad_map)
+ {
+ do_interp=true;
+ buildGrid();
+ }
+ writeMap(ofnam,mfnam,dfnam);
+ use_tcad_map=utmsaved;
+ do_interp = disaved;
+ return success;
+ }
+
+
+
private int getDoublesFromString(String str, double[] buf)
{
int blen = buf.length;
@@ -924,14 +1150,26 @@
public String getName() { return name; }
- public void buildGrid()
+ private void buildGrid()
{
gx0 = -fdimx/2.;
gy0 = -fdimy/2.;
gz0 = 0.;
+ if(gx0 < xmin) gx0 = xmin;
+ if(gy0 < ymin) gy0 = ymin;
+ if(gz0 < zmin) gz0 = zmin;
+ if(zmin < 0.) gz0 = zmin;
gpnx = ((int) Math.floor(fdimx/grdstx)) +1;
gpny = ((int) Math.floor(fdimy/grdsty)) +1;
gpnz = ((int) Math.floor(fdimz/grdstz)) +1;
+ /*
+ * we will ajust cell dimensions a little, to have the
+ * whole number of cells covering pixel volme
+ * (otherwise we may end up with left-right assimetry of the saved field)
+ */
+ grdstx = fdimx/(gpnx-1);
+ grdsty = fdimy/(gpny-1);
+ grdstz = fdimz/(gpnz-1);
gfldx = new double[gpnx][gpny][gpnz];
gfldy = new double[gpnx][gpny][gpnz];
gfldz = new double[gpnx][gpny][gpnz];
@@ -940,10 +1178,10 @@
double z=0.;
double[] p = new double[3];
double[] f = new double[3];
- System.out.println("Building ortogonal grid "+gpnx+" x "+gpny+" x "+gpnz+" = "+(gpnx*gpny*gpnz));
+ if(dbg_lvl > 0) System.out.println("Building ortogonal grid "+gpnx+" x "+gpny+" x "+gpnz+" = "+(gpnx*gpny*gpnz));
for(int i=0; i<gpnx; i++)
{
- System.out.println("Building "+i+"th x-layer");
+ if(dbg_lvl > 0) System.out.println("Building "+i+"th x-layer");
p[0]=gx0+i*grdstx;
for(int j=0; j<gpny; j++)
{
@@ -961,7 +1199,7 @@
}
- public void writeMap(String ofnam, String mfnam, String dfnam)
+ private void writeMap(String ofnam, String mfnam, String dfnam)
{
String cacheDir = System.getProperty("user.home");
File cachedir = new File(cacheDir);
@@ -1007,21 +1245,25 @@
}
- /** Get the field magnitude and direction at a particular point.
- * @param position The position at which the field is requested
- * @param b The field (the object is passed by reference and set to the correct field)
- */
-
+/**
+* Get the field magnitude and direction at a particular point.
+* @param position <code>double[]</code> The position at which the field is requested
+* @param b <code>double[]</code> Array to put result (field) in
+*/
public void getField(double[] position, double[] b)
{
getInterpolation(position,b);
}
- public void getInterpolation(double[] position, double[] b)
+ private void getInterpolation(double[] position, double[] b)
{
+ b[0]=0.;
+ b[1]=0.;
+ b[2]=0.;
double x = position[0]+tcad_dtol;
double y = position[1]+tcad_dtol;
double z = position[2]+tcad_dtol;
+ if((x<xmin-grdstx/2.) || (x>xmax+grdstx/2.) || (y<ymin-grdsty/2.) || (y>ymax+grdsty/2.) || (z<zmin-grdstz/2.) || (z>zmax+grdstz/2.)) return;
if(!use_tcad_map)
{
if(!map_read) return;