/* JRG, the Resource Geology Seismic Processing System for Java, and Viewmat for Java are Copyright 1998-2003 by John N. Louie The software and methods here are the subject of academic research, not commercial products. I would like to know what use you make of my methods, and have your feedback on their success or failure. Also, by letting me know who you are, I can inform you if bugs or errors are discovered. Please send me an email message with: your name and email address; whether you are a student or faculty member, consultant or employee; the name of your university or company, and department; and a sentence or two describing what use you intend to make of these methods. Send your message to louie@seismo.unr.edu */ import java.util.*; import java.io.*; import java.awt.*; import java.awt.event.*; public class ViewmatPicks extends Frame /*Dialog*/ implements ActionListener/*, ItemListener*/ { TextArea picktext; String planetext[]; /* buffer, by plane */ int plane; /* current plane displayed in picktext */ Button seisopt, save, close, extend, auto, showall, erase, hits; Viewmat vm; Viewmat vms[]; ViewmatFrame f; Menu threshmenu, dwinmenu; Panel pp; int xsize, ysize; float fxsize, fysize; StringBufferInputStream sbis; InputStreamReader isr; BufferedReader br; StringTokenizer st; float thresh; int dwin; public void actionPerformed(ActionEvent e) { ViewmatNotice vn; float fzoom; vm = f.vm; vms = f.vms; String label = e.getActionCommand(); if (label.equals("Close Pick Window") || label.equals("Close")) this.setVisible(false); else if (label.equals("Save Pick File...") || label.equals("Save")) { savePicks(); vm.cvs.repaint(); } else if (label.equals("Show All Planes...") || label.equals("Show All")) { showAllPicks(); } else if (label.equals("Export for SeisOpt...") || label.equals("SeisOpt")) { vn = new ViewmatNotice(f, "About Exporting Picks for SeisOpt", "SeisOpt's globally optimal discovery relies exclusively\n" + "on the picks and geometry you have here in your pick\n" + "window. To get good results from SeisOpt, please check\n" + "your picks and their locations very carefully. Correct\n" + "by hand any picks that are not accurate."); vn.show(); saveSeisOpt(); vm.cvs.repaint(); } /* else if (label.equals("Extend Pick")) { setCursor(Cursor.WAIT_CURSOR); extendPick(); vm.cvs.repaint(); setCursor(Cursor.DEFAULT_CURSOR); } */ else if (label.equals("Auto-Pick")) { setCursor(Cursor.WAIT_CURSOR); vn = new ViewmatNotice(f, "About Automatic Picking", "Auto-Pick uses a simple thresholding technique\n" + "that may or may not give you good first-arrival\n" + "picks. You must check all the picks in the data display,\n" + "and correct by hand any picks that are not accurate.\n" + "Trying different threshold settings in the Pick window's\n" + "View menu may improve Auto-Pick's results, but some\n" + "corrections are always needed."); vn.show(); autoPick(); vm.cvs.repaint(); setCursor(Cursor.DEFAULT_CURSOR); } else if (label.equals("Pick Hits")) { setCursor(Cursor.WAIT_CURSOR); pickHits(); vm.cvs.repaint(); setCursor(Cursor.DEFAULT_CURSOR); } else if (label.equals("First 10")) { dwin = 10; disableDwin(0); } else if (label.equals("First 50")) { dwin = 50; disableDwin(1); } else if (label.equals("First 100")) { dwin = 100; disableDwin(2); } else if (label.equals("First 500")) { dwin = 500; disableDwin(3); } else if (label.equals("125%")) { thresh = 1.25F; disableThresh(0); } else if (label.equals("200%")) { thresh = 2F; disableThresh(1); } else if (label.equals("500%")) { thresh = 5F; disableThresh(2); } else if (label.equals("1000%")) { thresh = 10F; disableThresh(3); } else if (label.equals("2500%")) { thresh = 25F; disableThresh(4); } else if (label.equals("10000%")) { thresh = 100F; disableThresh(5); } else if (label.equals("50000%")) { thresh = 500F; disableThresh(6); } else if (label.equals("Erase All Picks")) { eraseAll(); vm.cvs.repaint(); } else if (label.equals("About SeisOpt...")) aboutSeisOpt(); } public MenuBar makeMenuBar() { MenuItem open, save, optim; MenuBar mb = new MenuBar(); Menu file = new Menu("File", true); file.add(new MenuItem("Close Pick Window", new MenuShortcut(KeyEvent.VK_W))); file.add(new MenuItem("-")); file.add(save = new MenuItem("Save Pick File...", new MenuShortcut(KeyEvent.VK_S))); file.add(optim = new MenuItem("Export for SeisOpt...", new MenuShortcut(KeyEvent.VK_O))); mb.add(file); file.addActionListener(this); Menu edit = new Menu("Edit", true); /* edit.add(new MenuItem("Extend Pick")); */ edit.add(new MenuItem("Show All Planes...")); edit.add(new MenuItem("-")); edit.add(new MenuItem("Auto-Pick")); edit.add(new MenuItem("Pick Hits")); threshmenu = new Menu("Auto-Pick Threshold:", true); threshmenu.add(new MenuItem("125%")); threshmenu.add(new MenuItem("200%")); threshmenu.add(new MenuItem("500%")); threshmenu.add(new MenuItem("1000%")); threshmenu.add(new MenuItem("2500%")); threshmenu.add(new MenuItem("10000%")); threshmenu.add(new MenuItem("50000%")); threshmenu.getItem(2).setEnabled(false); edit.add(threshmenu); threshmenu.addActionListener(this); dwinmenu = new Menu("Threshold Above:", true); dwinmenu.add(new MenuItem("First 10")); dwinmenu.add(new MenuItem("First 50")); dwinmenu.add(new MenuItem("First 100")); dwinmenu.add(new MenuItem("First 500")); dwinmenu.getItem(0).setEnabled(false); edit.add(dwinmenu); dwinmenu.addActionListener(this); edit.add(new MenuItem("-")); edit.add(open = new MenuItem("Erase All Picks")); mb.add(edit); edit.addActionListener(this); Menu seisopt = new Menu("SeisOpt", true); seisopt.add(new MenuItem("About SeisOpt...")); seisopt.add(new MenuItem("Export for SeisOpt...")); mb.add(seisopt); seisopt.addActionListener(this); return mb; } public void disableThresh(int ind) { int i; if (ind < 0 || ind >= this.threshmenu.getItemCount()) return; for (i=0; i= this.dwinmenu.getItemCount()) return; for (i=0; i ne) dwin = ne; float vy[] = new float[ne]; int addr; float fsamp, fvec, fplane, amp; String pstr=""; boolean picked[], anypicks=false; picked = new boolean[planetext.length]; for (j=0; j= ne) continue; fsamp = e0 + isamp*de; fvec = v0 + i*dv; fplane = p0 + j*dp; amp = amp0 + damp*fv.vec[j*nv*ne + i*ne + isamp]; addr = j*nv + i; picked[j] = true; pstr = new String(pstr + Viewmat.getSignif("" + amp) + " " + isamp + " " + Viewmat.getSignif("" + fsamp) + " " + i + " " + Viewmat.getSignif("" + fvec) + " " + j + " " + Viewmat.getSignif("" + fplane) + (headers==null ? "\n" : " " + headers[addr].toString() + "\n")); } if (picked[j]) { planetext[j] = new String(pstr); anypicks = true; } } if (!anypicks) { Errout("No automatic picks could be made,\n" + "pick window untouched."); return; } else { for (j=0; j ne) dwin = ne; FltVec fvy = new FltVec(ne); float vy[] = fvy.vec; int addr, trace, nhits, hitsamp; trace = 0; float fsamp, fvec, fplane, amp, rms, temp; rms = 0F; String pstr=""; for (i=0; i rms) { rms = temp; trace = i; } } hitsamp = (int)(1F/de); if (hitsamp > ne/5) hitsamp = ne/5; else if (hitsamp < 500) hitsamp = 500; if (hitsamp < 10 || hitsamp > ne) hitsamp = ne; nhits = ne/hitsamp; for (k=0; k= ne) continue; fsamp = e0 + isamp*de; fvec = v0 + trace*dv; fplane = p0 + plane*dp; amp = amp0 + damp*fv.vec[plane*nv*ne +trace*ne + isamp]; addr = plane*nv + trace; pstr = new String(pstr + Viewmat.getSignif("" + amp) + " " + isamp + " " + Viewmat.getSignif("" + fsamp) + " " + trace + " " + Viewmat.getSignif("" + fvec) + " " + plane + " " + Viewmat.getSignif("" + fplane) + (headers==null ? "\n" : " " + headers[addr].toString() + "\n")); } picktext.setText(pstr); } public void aboutSeisOpt() { ViewmatNotice vn = new ViewmatNotice(f, "About SeisOpt", "The Power Beneath Your Fingertips (tm)\n" + "Contact Optim LLC at http://optimsoftware.com or (775) 784-6613\n" + "for software and services that will quickly and easily\n" + "get velocity sections from your first-arrival time picks.\n" + "Experience Globally Optimized Discovery applied to your\n" + "rippability, groundwater, or exploration problem."); vn.show(); } public void saveSeisOpt() { int i, j; /* save current text */ planetext[plane] = picktext.getText(); if (!anyPicks()) { Errout("No picks in window.\n" + "Pick first-arrival times on data image\n" + "before exporting for SeisOpt."); return; } f.fd.setMode(FileDialog.SAVE); f.fd.setTitle("Export Picks for SeisOpt..."); f.fd.setFile(ViewmatFrame.titleforfile(f.getTitle())); f.centerComp(f.fd); f.fd.show(); if (f.fd.getFile() == null) return; String path = f.fd.getDirectory() + f.fd.getFile(); FileOutputStream sfos = null; BufferedOutputStream sbos = null; PrintStream sps = null; FileOutputStream rfos = null; BufferedOutputStream rbos = null; PrintStream rps = null; FileOutputStream ofos = null; BufferedOutputStream obos = null; PrintStream ops = null; FileOutputStream rifos = null; BufferedOutputStream ribos = null; PrintStream rips = null; try { sfos = new FileOutputStream(path + ".src"); rfos = new FileOutputStream(path + ".rec"); ofos = new FileOutputStream(path + ".obs"); rifos = new FileOutputStream(f.fd.getDirectory() + "riotsinput"); } catch(IOException ioe) { Errout("Can't create SeisOpt files " + path + ".[src,rec,obs] and riotsinput due to: " + ioe.toString()); return; } sbos = new BufferedOutputStream(sfos); sps = new PrintStream(sbos); rbos = new BufferedOutputStream(rfos); rps = new PrintStream(rbos); obos = new BufferedOutputStream(ofos); ops = new PrintStream(obos); ribos = new BufferedOutputStream(rifos); rips = new PrintStream(ribos); int np, nv, ne; RgHead headers[]; float p0, dp, v0, dv, e0, de; if (vm.fvol == null) { np = 1; nv = vm.fp.vecs; ne = vm.fp.ne; headers = vm.fp.headers; p0 = 0F; dp = 1F; v0 = vm.fp.getUnit0ofDim(1); dv = vm.fp.getDUnitofDim(1); e0 = vm.fp.getUnit0ofDim(0); de = vm.fp.getDUnitofDim(0); } else { np = vm.fvol.planes; nv = vm.fvol.nv; ne = vm.fvol.ne; headers = vm.fvol.headers; p0 = vm.fvol.getUnit0ofDim(2); dp = vm.fvol.getDUnitofDim(2); v0 = vm.fvol.getUnit0ofDim(1); dv = vm.fvol.getDUnitofDim(1); e0 = vm.fvol.getUnit0ofDim(0); de = vm.fvol.getDUnitofDim(0); } float times[] = new float[np*nv]; float notime = -9e28F; for (i=0; i= 0 && pick.iplane < np && pick.ivec >= 0 && pick.ivec < nv && pick.isamp >= 0 && pick.isamp < ne) times[pick.iplane*nv + pick.ivec] = e0 + pick.isamp*de; } int count=0; for (i=0; i notime) count++; } if (count < 1) { Errout("No interpretable picks in pick window\n" + "Clear pick window and pick data again."); return; } int nSources=0; int nPicks=0; float res=-1F; double lastx=0.0, lasty=0.0, dist, gx, gy; for (j=0; j notime) { if (headers == null) rps.println("" + (v0 + i*dv) + " 0 0"); else rps.println("" + headers[j*nv + i].gx + " " + headers[j*nv + i].gy + " " + headers[j*nv + i].gz); if (lastx == 0.0 && lasty == 0.0) { lastx = headers==null ? (v0 + i*dv) : headers[j*nv + i].gx; lasty = headers==null ? 0 : headers[j*nv + i].gy; } else if (res < 0F) { gx = headers==null ? (v0 + i*dv) : headers[j*nv + i].gx; gy = headers==null ? 0 : headers[j*nv + i].gy; dist = Math.sqrt((gx-lastx)*(gx-lastx) + (gy-lasty)*(gy-lasty)); if (dist > 0.0) res = (float)(dist); lastx = gx; lasty = gy; } else { gx = headers==null ? (v0 + i*dv) : headers[j*nv + i].gx; gy = headers==null ? 0 : headers[j*nv + i].gy; dist = Math.sqrt((gx-lastx)*(gx-lastx) + (gy-lasty)*(gy-lasty)); if (dist > 0.0 && dist < res) res = (float)(dist); lastx = gx; lasty = gy; } ops.println("" + times[j*nv + i]); count++; nPicks++; } } if (count > 0) { if (headers == null) sps.println("" + (p0 + j*dp) + " 0 0 " + count); else sps.println("" + headers[j*nv].sx + " " + headers[j*nv].sy + " " + headers[j*nv].sz + " "+ count); nSources++; } } if (res <= 0F) res = 5F; rips.println("units=2"); rips.println("autocal=0"); /* rips.println("res=" + res); */ rips.println("res=5"); rips.println("nPicks=" + nPicks); rips.println("nSources=" + nSources); rips.println("obfil=" + path + ".obs"); rips.println("srcfil=" + path + ".src"); rips.println("recfil=" + path + ".rec"); rips.println("outdir=" + f.fd.getDirectory()); rips.println("ext=0"); rips.println("#"); rips.println("#Note: minimum station spacing is " + res + " meters."); try { sps.flush(); sbos.flush(); sfos.close(); rps.flush(); rbos.flush(); rfos.close(); ops.flush(); obos.flush(); ofos.close(); rips.flush(); ribos.flush(); rifos.close(); } catch(IOException ioe) { Errout("Can't write SeisOpt files " + path + ".[src,rec,obs] and riotsinput due to: " + ioe.toString()); return; } } public void savePicks() { f.fd.setMode(FileDialog.SAVE); f.fd.setTitle("Save Viewmat Picks File..."); f.fd.setFile(ViewmatFrame.titleforfile(f.getTitle()) + ".pck"); f.centerComp(f.fd); f.fd.show(); if (f.fd.getFile() == null) return; String path = f.fd.getDirectory() + f.fd.getFile(); FileOutputStream fos = null; BufferedOutputStream bos = null; PrintStream ps = null; try {fos = new FileOutputStream(path); } catch(IOException ioe) { Errout("Can't create picks file " + path + " due to: " + ioe.toString()); return; } bos = new BufferedOutputStream(fos); ps = new PrintStream(bos); /* save current text to buffer */ planetext[plane] = picktext.getText(); /* loop through planes in buffer */ for (int i=0; i 1) this.setTitle(f.getTitle() + " Plane " + this.plane + " Picks"); picktext.setText(planetext[plane]); } if (planetext[plane].length() < 8) return; PickData pick; /* just use text in plane's buffer */ Vector parsed = parsePicks(planetext[plane]); if (parsed == null || parsed.size() < 1) return; for (int i=0; i= 0 && pick.ivec >= 0) { x = getPickX(pick.ivec, pick.isamp); y = getPickY(pick.ivec, pick.isamp); g.drawRect(x, y, xsize, ysize); } } } public static float getPickpsX(int ivec, int isamp, boolean rowsdown, float imx, float fxsize) { float x; if (rowsdown) x = ivec*fxsize; else x = isamp*fxsize; return x+imx; } public static float getPickpsY(int ivec, int isamp, boolean rowsdown, float imy, float fysize) { float y; if (rowsdown) y = isamp*fysize; else y = ivec*fysize; return imy-y; } public static void pspicks(PrintStream ps, float xr, float yr, String text, int rnx, int rny, float xrsize, float yrsize, boolean sense, int plane) { float xsize, ysize, xpsize, ypsize; xsize = xrsize/rnx; ysize = yrsize/rny; xpsize = xsize; ypsize = ysize; if (xpsize < 2F) xpsize = 2F; if (ypsize < 2F) ypsize = 2F; if (plane < 0) plane = 0; float x, y; String line; if (text.length() < 8) return; PickData pick; Vector parsed = parsePicks(text); if (parsed == null || parsed.size() < 1) return; for (int i=0; i= 0 && pick.ivec >= 0) { x = getPickpsX(pick.ivec, pick.isamp, sense, xr, xsize); y = getPickpsY(pick.ivec, pick.isamp, sense, yr+yrsize, ysize); ps.println("" + x + " rxpos " + y + " rypos " + xpsize + " sclras -" + ypsize + " sclras pbox"); } } } void Errout(String err) { if (f.vm.fvol == null) f.vm.fp.Errout(err); else f.vm.fvol.Errout(err); } /* Constructors */ ViewmatPicks(ViewmatFrame f, Viewmat vm) { super(f.getTitle() + " Picks"); this.f = f; this.vm = vm; this.vms = null; this.thresh = 5F; this.dwin = 10; this.setMenuBar(makeMenuBar()); this.makePanel(); setPickSize(); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {setVisible(false); } }); } ViewmatPicks(ViewmatFrame f, Viewmat vms[]) { super(f.getTitle() + " Picks"); this.f = f; this.vm = vms[0]; this.vms = vms; this.thresh = 5F; this.dwin = 10; this.setMenuBar(makeMenuBar()); this.makePanel(); setPickSize(); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {setVisible(false); } }); } public void setPickSize() { if (vm.fvol == null) { if (vm.rowsdown) { fxsize = (float)(vm.imw)/vm.fp.vecs; fysize = (float)(vm.imh)/vm.fp.ne; } else { fxsize = (float)(vm.imw)/vm.fp.ne; fysize = (float)(vm.imh)/vm.fp.vecs; } } else { if (vm.rowsdown) { fxsize = (float)(vm.imw)/vm.fvol.nv; fysize = (float)(vm.imh)/vm.fvol.ne; } else { fxsize = (float)(vm.imw)/vm.fvol.ne; fysize = (float)(vm.imh)/vm.fvol.nv; } } xsize = (int)(fxsize); if (xsize < 2) xsize = 2; ysize = (int)(fysize); if (ysize < 2) ysize = 2; } public void makePanel() { this.setVisible(false); Color ltgray = new Color(220, 220, 220); this.setBackground(ltgray); this.setTitle(f.getTitle() + " Picks"); pp = new Panel(new FlowLayout()); pp.setSize(470, 525); pp.setBackground(ltgray); picktext = new TextArea("", 24, 48); pp.add(picktext); this.plane = 0; if (f.vm.fvol == null) planetext = new String[1]; else planetext = new String[f.vm.fvol.planes]; for (int i=0; i= 8) return true; } return false; } /* Count vectors that have one or more picks */ static public int getNPicked(FltPlane fp) { int np, nv, npicked, i; if (fp.f.picks.anyPicks() == false) return 0; boolean picked[] = new boolean[fp.vecs]; for (i=0; i= 0 && pick.iplane < np && pick.ivec >= 0 && pick.ivec < nv) picked[pick.iplane*nv + pick.ivec] = true; } npicked = 0; for(i=0; i= 0 && pick.iplane < np && pick.ivec >= 0 && pick.ivec < nv) picked[pick.iplane*nv + pick.ivec] = true; } for(i=0; i= 0 && pick.iplane < 1e15 && pick.ivec >= 0 && pick.ivec < 1e15 && pick.isamp >= 0 && pick.isamp < 1e15) parsed.addElement(new PickData(pick)); } } catch (IOException ioe) { return parsed; } return parsed; } /* Show all picks in a Viewmat Notice window */ public void showAllPicks() { planetext[plane] = picktext.getText(); String allpicks = new String(planetext[0]); for (int i=1; i