/* JRG, the Resource Geology Seismic Processing System for Java, and Viewmat for Java are Copyright 1998-2000 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 ViewmatGeom extends Frame /*Dialog*/ implements ActionListener /*, ItemListener*/ { Choice geomch, meterch; TextArea geomtext; Button apply, close, erase, clear, format, read, write, show; Viewmat vm; Viewmat vms[]; ViewmatFrame f; Panel pp; int xsize, ysize; float fxsize, fysize; StringBufferInputStream sbis; InputStreamReader isr; BufferedReader br; StringTokenizer st; Vector coords; public void actionPerformed(ActionEvent e) { ViewmatNotice vn; vm = f.vm; vms = f.vms; String label = e.getActionCommand(); if (label.equals("Close Geometry Window") || label.equals("Close")) this.setVisible(false); else if (label.equals("Apply Geometry") || label.equals("Apply")) { applyGeom(); } else if (label.equals("Erase All Geometry") || label.equals("Erase All")) { eraseGeom(); geomtext.setText("All shot, receiver, and offset information has been erased\n" + "from the data headers. With no geometry headers, methods\n" + "requiring geometric information will make use of the\n" + "labels on the vectors and planes as defined in the\n" + "Plot Parameters window and shown on the data display."); } else if (label.equals("Clear Window") || label.equals("Clear")) { geomtext.setText("Window text cleared;\n" + "no changes made to any geometric headers or\n" + "labeling of the data."); } else if (label.equals("Show Input Format") || label.equals("Show Format")) { showFormat(); } else if (label.equals("Read File...") || label.equals("Read File")) { readFile(); } else if (label.equals("Write Headers to File...") || label.equals("Write File")) { writeFile(); } else if (label.equals("Show All Headers") || label.equals("Show All")) { showHeaders(); } } public MenuBar makeMenuBar() { MenuBar mb = new MenuBar(); Menu file = new Menu("File", true); file.add(new MenuItem("Close Geometry Window", new MenuShortcut(KeyEvent.VK_W))); file.add(new MenuItem("-")); file.add(new MenuItem("Read File", new MenuShortcut(KeyEvent.VK_O))); file.add(new MenuItem("Write Headers to File", new MenuShortcut(KeyEvent.VK_S))); file.add(new MenuItem("-")); file.add(new MenuItem("Apply Geometry", new MenuShortcut(KeyEvent.VK_A))); mb.add(file); file.addActionListener(this); Menu edit = new Menu("Edit", true); edit.add(new MenuItem("Apply Geometry", new MenuShortcut(KeyEvent.VK_A))); edit.add(new MenuItem("-")); edit.add(new MenuItem("Show Input Format", new MenuShortcut(KeyEvent.VK_F))); edit.add(new MenuItem("Show All Headers", new MenuShortcut(KeyEvent.VK_H))); edit.add(new MenuItem("-")); edit.add(new MenuItem("Clear Window")); edit.add(new MenuItem("Erase All Geometry")); mb.add(edit); edit.addActionListener(this); return mb; } public void showHeaders() { RgHead headers[]; if (vm.fvol == null) headers = vm.fp.headers; else headers = vm.fvol.headers; if (headers == null) { geomtext.setText("This data set has no geometry headers.\n" + "Use the Type selector above and the Show Format\n" + "button to read about the types of information needed\n" + "to define survey geometry and create the headers.\n"); return; } String buf = ""; for (int i=0; i 0) geomtext.setText(new String(buf)); else { f.Errout("File " + path + " does not appear to contain any text."); } try { in.close(); fr.close(); } catch(IOException ioe) { f.Errout("Can't close geometry file " + path + " after reading."); } } public void writeFile() { RgHead headers[]; if (vm.fvol == null) headers = vm.fp.headers; else headers = vm.fvol.headers; if (headers == null) { f.Errout("This data set has no geometry headers;" + " cannot save headers to a file."); return; } f.fd.setMode(FileDialog.SAVE); f.fd.setTitle("Save JRG Header File..."); f.fd.setFile(ViewmatFrame.titleforfile(f.getTitle()) + ".ahd"); 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) { f.Errout("Can't create header file " + path + " due to: " + ioe.toString()); return; } bos = new BufferedOutputStream(fos); ps = new PrintStream(bos); for (int i=0; i10 meters, for all but highest-res. work),\n" + "as with deeply drilled blasts, sources and\n" + "receivers must have separate numbering\n" + "systems, with separate elevations. A similar\n" + "scheme is needed if vibe moveup patterns\n" + "do not match geophone group patterns. Station\n" + "coordinates should not be for flag locations;\n" + "the coordinates must be for the actual source\n" + "and receiver pattern centers."); else if (geomch.getSelectedIndex() == 2) geomtext.setText("Station Coords - N Z Y X selected above.\n" + "Copy from your spreadsheet and paste into this\n" + "window one line for each station number\n" + "referenced in the observer's report or existing\n" + "headers, in the following format. Entries on\n" + "each line are separated by a space or tab.\n" + "You may also need to load an observer's report\n" + "and apply it separately.\n\n" + "staID Elevation Ycoord Xcoord\n\n" + "where staID is the integer station number,\n" + "Xcoord is the horizontal X-axis coordinate\n" + "(or longitude) in the selected system of units,\n" + "Ycoord is the horizontal Y-axis coordinate\n" + "(or latitude), and Elevation is the vertical\n" + "height of the station's source or receiver\n" + "above sea level or other datum. If sources\n" + "and receivers at the same station locations\n" + "may have significantly different elevations\n" + "(>10 meters, for all but highest-res. work),\n" + "as with deeply drilled blasts, sources and\n" + "receivers must have separate numbering\n" + "systems, with separate elevations. A similar\n" + "scheme is needed if vibe moveup patterns\n" + "do not match geophone group patterns. Station\n" + "coordinates should not be for flag locations;\n" + "the coordinates must be for the actual source\n" + "and receiver pattern centers."); else if (geomch.getSelectedIndex() == 3) geomtext.setText("Ascii Trace Headers selected above.\n" + "Copy from your spreadsheet and paste into this\n" + "window one line for each trace in this data set,\n" + "in the following format. Entries on\n" + "each line are separated by a space or tab.\n\n" + "rec svp gvp sx sy sz gx gy gz off\n\n" + "This data set has " + (np*nv) + " traces.\n" + "All coordinates must be in meters\n" + "(or lat/lon degrees) since this input form\n" + "ignores the unit system selected above.\n" + "rec is the field record number, svp is the\n" + "source location number, gvp is the receiver\n" + "location number, sx is the source x-coordinate,\n" + "sy is the source y-coordinate, sz is the source\n" + "z-coordinate, gx is the receiver x-coordinate,\n" + "gy is the receiver y-coordinate, gz is the\n" + "receiver z-coordinate, and off is the offset in\n" + "meters."); } public void applyGeom() { int i, j, k, l, lines, channels, temp; int np, nv, ne, isamp; RgHead headers[], newhd[]; float p0, dp, v0, dv, e0, de, amp0, damp; FltPlane fp; int rec, svp, gvp; double sx, sy, sz, gx, gy, gz, off, dtemp; int npatch[], igvp[][], fgvp[][], recs[], svps[]; String line, errcollect; errcollect = ""; boolean geogr, test, stest; Coord coord; if (geomtext.getText().length() < 7) { geomtext.setText("Not enough data in geometry window to change or apply\n" + "any geometry information to the current data set.\n\n" + "Select a type of input geometry above and press the\n" + "Show Format button below to read about the types of\n" + "geometry information needed."); return; } 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); amp0 = vm.fp.getAmp0(); damp = vm.fp.getAmpFac(); fp = vm.fp; } 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); amp0 = vm.fvol.getAmp0(); damp = vm.fvol.getAmpFac(); fp = vm.fvol; } if (meterch.getSelectedIndex() == 2 || meterch.getSelectedIndex() == 3) geogr = true; else geogr = false; if (vm.fvol == null) vm.fp.geogr = geogr; else vm.fvol.geogr = geogr; sbis = new StringBufferInputStream(geomtext.getText()); isr = new InputStreamReader(sbis); br = new BufferedReader(isr); if (geomch.getSelectedIndex() == 3) { lines = 0; headers = new RgHead[np*nv]; rec = svp = gvp = -1; gx = gy = gz = sx = sy = sz = 0.0; off = -1.0; try { while ((line = br.readLine()) != null) { if (line.length() < 19) continue; st = new StringTokenizer(line); if (st.hasMoreTokens()) { try {rec = Integer.valueOf(st.nextToken()).intValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {svp = Integer.valueOf(st.nextToken()).intValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {gvp = Integer.valueOf(st.nextToken()).intValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {sx = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {sy = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {sz = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {gx = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {gy = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {gz = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {off = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (lines < headers.length) { headers[lines] = new RgHead(); headers[lines].set(rec, svp, gvp, sx, sy, sz, gx, gy, gz, off); } lines++; } } catch (IOException ioe) { f.Errout("Internal IOException reading geometry text;\n" + "attempting to continue applying:\n" + ioe); } if (lines < headers.length) { f.Errout("Only " + lines + " valid lines of ascii headers read,\n" + "but data set has " + headers.length + " traces.\n" + "No geometry headers applied or changed."); return; } else if (lines > headers.length) f.Errout("" + lines + " valid lines of ascii headers read,\n" + "but data set has only " + headers.length + " traces.\n" + "Only the first " + headers.length + " lines of ascii headers were applied to the traces."); fp.headers = headers; coords = null; geomtext.setText("Successfully applied " + headers.length + " lines of ascii headers to the traces;\n" + "Data set now has " + fp.getOffsets()); } else if (geomch.getSelectedIndex() == 1 || geomch.getSelectedIndex() == 2) { lines = 0; rec = svp = gvp = -1; gx = gy = gz = sx = sy = sz = 0.0; off = -1.0; coords = new Vector(nv, nv); try { while ((line = br.readLine()) != null) { if (line.length() < 7) continue; st = new StringTokenizer(line); if (st.hasMoreTokens()) { try {svp = Integer.valueOf(st.nextToken()).intValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {sx = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {sy = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (st.hasMoreTokens()) { try {sz = Double.valueOf(st.nextToken()).doubleValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (geomch.getSelectedIndex() == 1) coord = new Coord(svp, sx, sy, sz); else coord = new Coord(svp, sz, sy, sx); if (meterch.getSelectedIndex() == 0) coord.convertFeetToMeters(); coords.addElement(coord); lines++; } } catch (IOException ioe) { f.Errout("Internal IOException reading geometry text;\n" + "attempting to continue applying:\n" + ioe); } if (lines < 1) { f.Errout("No valid lines of station coordinates read.\n" + "No geometry headers applied or changed."); return; } if (headers == null) { geomtext.setText("" + lines + " valid lines of station coordinates read\n" + (meterch.getSelectedIndex() == 0 ? "and converted from feet to meters.\n" : "\n") + "To complete labeling of your traces with geometric\n" + "headers, you need to copy and paste observer's report\n" + "lines into this window, select the Observer's Report\n" + "type of input geometry, and press the Apply button\n" + "again. This data set has " + np + " records (planes),\n" + "so you will need to supply " + np + " observer's-report\n" + "lines."); } else { test = true; newhd = new RgHead[headers.length]; System.arraycopy(headers, 0, newhd, 0, headers.length); for (i=0; i= np) { lines++; continue; } if (st.hasMoreTokens()) { try {npatch[lines] = Integer.valueOf(st.nextToken()).intValue(); } catch (NumberFormatException nfe) {continue; } } else continue; if (npatch[lines] < 1 || npatch[lines] > 1000000000) continue; igvp[lines] = new int[npatch[lines]]; fgvp[lines] = new int[npatch[lines]]; recs[lines] = rec; svps[lines] = svp; channels = 0; for (i=0; i 1000000000 || fgvp[lines][i] < 0 || fgvp[lines][i] > 1000000000) continue; if (igvp[lines][i] > fgvp[lines][i]) temp = igvp[lines][i] - fgvp[lines][i] + 1; else temp = fgvp[lines][i] - igvp[lines][i] + 1; channels += temp; } if (i != npatch[lines]) continue; if (channels != nv) errcollect += "Observer's rept line for rec=" + rec + " svp=" + svp + " npatch=" + npatch + " invalid: " + channels + " patch channels defined, not equal to " + nv + " traces per record.\n"; lines++; } } catch (IOException ioe) { f.Errout("Internal IOException reading geometry text;\n" + "attempting to continue applying:\n" + ioe); } if (errcollect.length() > 20) f.Errout(errcollect); if (lines < np) { f.Errout("Only " + lines + " valid lines of observer's report read,\n" + "but data set has " + np + " records (planes).\n" + "No geometry headers applied or changed."); return; } else if (lines > np) f.Errout("" + lines + " valid lines of observer's report read,\n" + "but data set has only " + np + " records (planes).\n" + "Only the first " + np + " lines of valid observer's report\nwere applied to the records."); for (i=0; i fgvp[i][j]) for (k=igvp[i][j]; k >= fgvp[i][j]; k--) { headers[i*nv + l].rec = recs[i]; headers[i*nv + l].svp = svps[i]; headers[i*nv + l].gvp = k; if (headers[i*nv + l].allset) headers[i*nv + l].off = headers[i*nv + l].calcOffset(geogr); l++; } else for (k=igvp[i][j]; k <= fgvp[i][j]; k++) { headers[i*nv + l].rec = recs[i]; headers[i*nv + l].svp = svps[i]; headers[i*nv + l].gvp = k; if (headers[i*nv + l].allset) headers[i*nv + l].off = headers[i*nv + l].calcOffset(geogr); l++; } } } fp.headers = headers; if (coords == null) { test = true; for (i=0; i