vtk學習筆記——利用vtk顯示地震數據

多年來一直從事技術開發,越來越覺得自己知識太少,基本屬於無知的行列,所以不敢寫blog,心虛。。。

最近在研究vtk顯示地震數據的問題,通過閱讀之前其他網友所提供的vtk學習筆記,收穫不少,特此表示感謝。

本着拋磚引玉的原則,把自己的一些心得寫出來,期待大家拍磚。謝謝!

——————————————————————————————————————————————

地震的常見數據格式之一,segy,目前存在兩個標準,1975年和2002年,後一版本儘量做到了向前兼容。

通過網上下載到了英文版的數據格式說明和中文版,感謝中文版作者的分享。

本人通過閱讀數據格式規範,結合java,進行了數據的vtk顯示。

由於不知道怎麼發附件,只能把源碼貼在下面,見諒各位。

核心類爲SegyReader,它包括了卷頭、道頭、道數據的組織,道頭和道數據都封裝在了SegyTrace類裏,這個類裏實現了從IBM浮點數到java的轉換(ps:這個費了偶不少勁,遍閱很多資料,反覆若干次才弄對,所謂對是通過發佈文章上的16進製表示的ibm浮點數與十進制的對應關係驗證而得)。其中SimpleVTK2這個類裏,封裝了顯示部分。很簡單,呵呵,沒做特殊處理,只是把一道數據做成一條線,拋磚引玉,請各位評判。

閒話不說了,上代碼:

____________________________      SegyReader類     _________________________________________________________________________________

package org.sinoprobe.segy;

import java.awt.BorderLayout;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import org.sinoprobe.util.Util4JavaBean;
/**
 * segy數據文件讀取類
 * 它包括了對segy文件所包含全部數據對象的封裝
 *
 * @author dingyi
 *
 */
public class SegyReader {
 
 private String filePath;
 private SegyTextFileHeader txtHdr;
 private SegyReelHdr reelHdr;
 private ArrayList<SegyTrace> traceList=new ArrayList<SegyTrace>();
 

 /**
  * 構造Segy讀取對象
  * @param filePath  segy文件名,包括全路徑
  */
 public SegyReader(String filePath) {
  super();
  this.filePath = filePath;
 }
 
 
 public void buildFromFile() throws IOException, SegyFileFormatException{
  FileInputStream fis = new FileInputStream(filePath);
  DataInputStream dis = new DataInputStream(fis);
  // 首先讀取前3200字節的文本頭
  byte[] buf = new byte[3200];
  dis.readFully(buf);
  byte[] b = CodeUtil.EBCDICToASCII(buf);
  txtHdr = new SegyTextFileHeader(b);
  //判斷是否合法,即是否每一行均以C開頭,如果不合法,那麼,可能會是存在帶頭標籤
  if(!txtHdr.isValid()){
   throw new SegyFileFormatException("卷頭數據不是以C開頭,可能存在標籤對象,請嘗試用另外方法讀取!");
  }
  
  //繼續讀取卷頭數據
  buf = new byte[400];
  dis.readFully(buf);
  reelHdr = new SegyReelHdr(buf);
  //判斷是否有擴展卷頭
  if(reelHdr.has_extend_text_hdr_flag!=0){
   //此時有3200字節的擴展原文文件頭
   //需要執行讀取動作,此處暫空,以拋出異常爲處理手段
   throw new SegyFileFormatException("存在擴展原文文件頭,需要讀取!");
  }
  //繼續讀取道數據
  //強制讀取卷頭所標記的
 //for (int i = 0; i <reelHdr.traces_per_record; i++)
  while(dis.available()>0) {
   // 首先讀取道頭
   buf = new byte[240];
   dis.readFully(buf);
   SegyTrace oneTrace = new SegyTrace(buf);
   // 根據卷頭和道頭得出要讀取的數據塊的大小
   int dataCount = oneTrace.samples_in_this_trace
     * reelHdr.getMultiple();
   //讀取道數據
   buf = new byte[dataCount];
   dis.readFully(buf);
   oneTrace.readDataInIBMFormat(buf);
   //添加到道列表中
   traceList.add(oneTrace);
   
  }
  System.out.println("讀取道數據結束");

  dis.close();
  fis.close();
  
 }


 /**
  * 得到原文文件頭,文本格式
  * @return
  */
 public SegyTextFileHeader getTxtHdr() {
  return txtHdr;
 }

 /**
  * 得到卷(道集)頭數據
  * @return
  */
 public SegyReelHdr getReelHdr() {
  return reelHdr;
 }

 /**
  * 得到道數據列表
  * @return
  */
 public ArrayList<SegyTrace> getTraceList() {
  return traceList;
 }
 /**
  * 得到測量到的最大最小值
  * @return  順序爲min,Max
  */
 public double[] getMinMaxValue(){
  double[] minMax=new double[2];
  minMax[0]=0;
  minMax[1]=0;
  for(SegyTrace t:traceList){
   for(double d: t.data){
    if(d>minMax[1])
     minMax[1]=d;
    if(d<minMax[0])
     minMax[0]=d;
   }
  }
  return minMax;
 }
 public static void main(String[] args) {
  SegyReader reader=new SegyReader("f:\\3002.sgy");
  try {
   reader.buildFromFile();
   System.out.println("數據讀取完成!開始構造vtk顯示");
   
   //構造vtk界面
    final SimpleVTK2 vtkPanel=new SimpleVTK2(reader);
    SwingUtilities.invokeLater(new Runnable() {
              @Override
              public void run() {
                  JFrame frame = new JFrame("SimpleVTK");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  frame.getContentPane().setLayout(new BorderLayout());
                  frame.getContentPane().add(vtkPanel);
                  frame.setSize(640, 480);
                  frame.setLocationRelativeTo(null);
                  frame.setVisible(true);
              }
          });
   

  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (SegyFileFormatException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }
}
————————————————   SegyReelHdr 類————————————————————————————————————

package org.sinoprobe.segy;


/**
 * 表2. 二進制文件頭
400字節二進制文件頭
字節 描述
3201-3204 作業標識號
3205-3208 測線號。對3-D疊後數據而言,它將典型地包含縱向測線(In-line)號
3209-3212 卷號
3213-32145 每個道集的數據道數。疊前數據強制要求
3215-32165 每個道集的輔助道數。疊前數據強制要求
3217-32186 微秒(us)形式的採樣間隔。疊前數據強制要求
3219-3220 微秒(us)形式的原始野外記錄採樣間隔
3221-32226 數據道採樣點數。疊前數據強制要求
註釋:二進制文件頭中的採樣間隔和採樣點數應當是文件中地震數據的首要一組參數
3223-3224 原始野外記錄每道採樣點數
3225-32266 數據採樣格式編碼。疊前數據強制要求
1=4字節IBM浮點數
2=4字節,兩互補整數
3=2字節,兩互補整數
4=4字節帶增益定點數(過時,不再使用)
5=4字節IEEE浮點數
6=現在沒有使用
7=現在沒有使用
8=1字節,兩互補整數
3227-32287 道集覆蓋次數――每個數據集的期望數據道數(例如CMP覆蓋次數)。強烈推薦所有類型的數據使用
3229-32307 道分選碼(即集合類型):
-1=其他(應在用戶擴展文件頭文本段中解釋)
0=未知
1=同記錄(未分選)
2=CDP道集
3=單次覆蓋連續剖面
4=水平疊加
5=共炮點
6=共接收點
7=共偏移距
8=共中心點
9=共轉換點
強烈推薦所有類型的數據使用
3231-3232 垂直求和碼:
1=不求和
2=兩次求和

M=M-1求和(M=2到32767)
3233-3234 起始掃描頻率(Hz)
3235-3236 終止掃描頻率(Hz)
3237-3238 掃描長度(ms)
3239-3240 掃描類型碼:
1=線性
2=拋物線
3=指數
4=其他
3241-3242 掃描信道的道數
3243-3244 有斜坡時,以毫秒錶示的掃描道起始斜坡長度(斜坡從零時刻開始,對這個長度有效)
3245-3246 以毫秒錶示的掃描道終止斜坡長度(斜坡終止始於掃描長度減去斜坡結尾處的長度)
3247-3248 斜坡類型:
1=線性
2=cos2
3=其他
3249-3250 相關數據道:
1=無相關
2=相關
3251-3252 二進制增益恢復:
1=恢復
2=未恢復
3253-3254 振幅恢復方法:
1=無
2=球面擴散
3=自動增益控制
4=其他
3255-32567 測量系統:強烈推薦所有類型的數據使用。如文件中包含位置數據文本段,這條必須與位置數據文本段一致。如不同,最後位置數據文本段有控制權。
1=米
2=英尺
3257-3258 脈衝極化碼:
1=壓力增大或檢波器向上運動在磁帶上記作負數
2=壓力減小或檢波器向下運動在磁帶上記作正數
3259-3260 可控源極化碼:
地震信號滯後引導信號:
1=337.5°-22.5°
2=22.5°-67.5°
3=67.5°-112.5°
4=112.5°-157.5°
5=157.5°-202.5°
6=202.5°-247.5°
7=247.5°-292.5°
8=292.5°-337.5°
3261-3500 未賦值
3501-3502 6 SEG Y格式修訂版號。這是一個16比特無符號數值,在第一和第二字節間有Q點。例如SEG Y修訂版1.0,如文檔定義,它將記錄爲0100 。此字段對所有SEG Y版本強制要求,儘管零值表示遵從1975年標準的“傳統”SEG Y
3503-3504 6 固定長度道標誌。1表示SEG Y文件中所有道確保具有相同的採樣間隔和採樣點數,即在原文文件頭中3217-3218和3221-3222字節。0表示文件中的道長可能變化,此時道頭中115-116字節的採樣點數必須用來確認各道的實際長度。此字段對所有SEG Y版本強制要求,儘管零值表示遵從1975年標準的“傳統”SEG Y
3505-3506 6 3200字節擴展原文文件頭記錄在二進制頭後。0表示沒有擴展原文文件頭記錄(即此文件無擴展原文文件頭)。-1表示擴展原文文件頭記錄數可變,並且擴展原文文件頭結尾用最終記錄的一個文本段((SEG: ENDText))表示。正值表示有很多原文文件頭。注意雖然具體的擴展原文文件頭數目是個有用的信息,但是在寫二進制頭時它並不是總知道也不是強制要求在此記錄正值。此字段對所有SEG Y版本強制要求,儘管零值表示遵從1975年標準的“傳統”SEG Y
3507-3600 未賦值
 
5 此信息對疊前數據強制要求。
6 此信息對所有數據類型強制要求。
7 強烈建議此信息一直被記錄。

 * @author dingyi
 *
 */
public class SegyReelHdr {
 // 3201-3204 作業標識號
 int job_id_number;

 // 3205-3208 測線號。對3-D疊後數據而言,它將典型地包含縱向測線(In-line)號
 int line_number;

 // 3209-3212 卷號
 int reel_number;

 // 3213-3214 每個道集的數據道數。疊前數據強制要求
 short traces_per_record;

 // 3215-3216 每個道集的輔助道數。疊前數據強制要求
 short aux_traces_per_record;

 // 3217-3218 微秒(us)形式的採樣間隔。疊前數據強制要求
 short sample_data_interval_ms;

 // 3219-3220 微秒(us)形式的原始野外記錄採樣間隔
 short original_data_interval_ms;

 // 3221-3222 數據道採樣點數。疊前數據強制要求
 // 註釋:二進制文件頭中的採樣間隔和採樣點數應當是文件中地震數據的首要一組參數
 short samples_per_trace;

 // 3223-3224 原始野外記錄每道採樣點數
 short original_samples_per_trace;

 // 3225-3226 數據採樣格式編碼。疊前數據強制要求
 /**
  * 1=4字節IBM浮點數 2=4字節,兩互補整數 3=2字節,兩互補整數 4=4字節帶增益定點數(過時,不再使用) 5=4字節IEEE浮點數
  * 6=現在沒有使用 7=現在沒有使用 8=1字節,兩互補整數
  */
 short data_sample_format_code;// 數據採樣格式編碼

 // 3227-32287 道集覆蓋次數――每個數據集的期望數據道數(例如CMP覆蓋次數)。強烈推薦所有類型的數據使用
 short CDP_fold;

 // 3229-32307 道分選碼(即集合類型):
 /**
  * -1=其他(應在用戶擴展文件頭文本段中解釋) 0=未知 1=同記錄(未分選) 2=CDP道集 3=單次覆蓋連續剖面 4=水平疊加 5=共炮點
  * 6=共接收點 7=共偏移距 8=共中心點 9=共轉換點 強烈推薦所有類型的數據使用
  */
 short trace_sorting_code;// 3229-32307 道分選碼(即集合類型):

 // 3231-3232 垂直求和碼:
 /*
  * 1=不求和 2=兩次求和 … M=M-1求和(M=2到32767)
  */
 short vertical_sum_code;

 // 3233-3234 起始掃描頻率(Hz)
 short sweep_frequency_start_hz;

 // 3235-3236 終止掃描頻率(Hz)
 short sweep_frequency_end_hz;

 // 3237-3238 掃描長度(ms)
 short sweep_length_ms;

 // 3239-3240 掃描類型碼:
 /**
  * 1=線性 2=拋物線 3=指數 4=其他
  */
 short sweep_type_code;

 // 3241-3242 掃描信道的道數
 short trace_number_of_sweep_channel;

 // 3243-3244 有斜坡時,以毫秒錶示的掃描道起始斜坡長度(斜坡從零時刻開始,對這個長度有效)
 short sweep_trace_taper_length_start_ms;

 // 3245-3246 以毫秒錶示的掃描道終止斜坡長度(斜坡終止始於掃描長度減去斜坡結尾處的長度)
 short sweep_trace_taper_length_end_ms;

 /**
  * 3247-3248 斜坡類型: 1=線性 2=cos2 3=其他
  */
 short taper_type_code;

 // 3249-3250 相關數據道:
 // 1=無相關
 // 2=相關
 short correlated_data_traces_flag;

 /**
  * 3251-3252 二進制增益恢復: 1=恢復 2=未恢復
  **/
 short binary_gain_recovered_flag;

 /**
  * 3253-3254 振幅恢復方法: 1=無 2=球面擴散 3=自動增益控制 4=其他*
  */
 short amplitude_recovery_method_code;

 /**
  * 3255-32567
  * 測量系統:強烈推薦所有類型的數據使用。如文件中包含位置數據文本段,這條必須與位置數據文本段一致。如不同,最後位置數據文本段有控制權。 1=米
  * 2=英尺
  **/
 short measurement_system;

 /**
  * 3257-3258 脈衝極化碼: 1=壓力增大或檢波器向上運動在磁帶上記作負數 2=壓力減小或檢波器向下運動在磁帶上記作正數
  **/
 short impulse_signal_polarity;

 /**
  * 3259-3260 可控源極化碼: 地震信號滯後引導信號: 1=337.5°-22.5° 2=22.5°-67.5° 3=67.5°-112.5°
  * 4=112.5°-157.5° 5=157.5°-202.5° 6=202.5°-247.5° 7=247.5°-292.5°
  * 8=292.5°-337.5°
  **/
 short vibratory_polarity_code;

 // 3261-3500 未賦值
 // 3501-3502 6 SEG Y格式修訂版號。這是一個16比特無符號數值,在第一和第二字節間有Q點。例如SEG
 // Y修訂版1.0,如文檔定義,它將記錄爲0100 。此字段對所有SEG Y版本強制要求,儘管零值表示遵從1975年標準的“傳統”SEG Y
 short segy_version;
 // 3503-3504 6 固定長度道標誌。1表示SEG
 // Y文件中所有道確保具有相同的採樣間隔和採樣點數,即在原文文件頭中3217-3218和3221-3222字節。0表示文件中的道長可能變化,此時道頭中115-116字節的採樣點數必須用來確認各道的實際長度。此字段對所有SEG
 // Y版本強制要求,儘管零值表示遵從1975年標準的“傳統”SEG Y
 short fix_length_trace_flag;
 // 3505-3506 6
 // 3200字節擴展原文文件頭記錄在二進制頭後。0表示沒有擴展原文文件頭記錄(即此文件無擴展原文文件頭)。-1表示擴展原文文件頭記錄數可變,並且擴展原文文件頭結尾用最終記錄的一個文本段((SEG:
 // ENDText))表示。正值表示有很多原文文件頭。注意雖然具體的擴展原文文件頭數目是個有用的信息,但是在寫二進制頭時它並不是總知道也不是強制要求在此記錄正值。此字段對所有SEG
 // Y版本強制要求,儘管零值表示遵從1975年標準的“傳統”SEG Y
 short has_extend_text_hdr_flag;// 如果不爲0,則有擴展的3200個標頭

 // 3507-3600 未賦值

 public SegyReelHdr(byte[] b) {
  int i = 0;
  job_id_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 4;
  line_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 8;
  reel_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 12;
  traces_per_record = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 14;
  aux_traces_per_record = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 16;
  sample_data_interval_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 18;
  original_data_interval_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 20;
  samples_per_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 22;
  original_samples_per_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 24;
  data_sample_format_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 26;
  CDP_fold = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 28;
  trace_sorting_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 30;
  vertical_sum_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 32;
  sweep_frequency_start_hz = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 34;
  sweep_frequency_end_hz = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 36;
  sweep_length_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 38;
  sweep_type_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 40;
  trace_number_of_sweep_channel = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 42;
  sweep_trace_taper_length_start_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 44;
  sweep_trace_taper_length_end_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 46;
  taper_type_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 48;
  correlated_data_traces_flag = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 50;
  binary_gain_recovered_flag = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 52;
  amplitude_recovery_method_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 54;
  measurement_system = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 56;
  impulse_signal_polarity = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 58;
  vibratory_polarity_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  // 3261-3500 未賦值
  i = 300;
  segy_version = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 302;
  fix_length_trace_flag = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 304;
  has_extend_text_hdr_flag = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  // 3507-3600 未賦值
 }


 /**
  * 得到編碼格式對應的倍數
  * 依據2002年segy數據規範
  *
  * 1=4字節IBM浮點數 2=4字節,兩互補整數 3=2字節,兩互補整數 4=4字節帶增益定點數(過時,不再使用) 5=4字節IEEE浮點數
  * 6=現在沒有使用 7=現在沒有使用 8=1字節,兩互補整數
  */

 public int getMultiple() throws SegyFileFormatException {
  switch (this.data_sample_format_code) {
  case 1:
  case 2:
  case 4:
  case 5:
   return 4;
  case 3:
   return 2;
  case 8:
   return 1;
  }
  throw new SegyFileFormatException("編碼類型參數錯誤");
 }

}

___________________________    SegyTrace類     __________________________________________________________

package org.sinoprobe.segy;


/**
 * Segy道
 * 包括道頭和道數據
 * 參照Segy 2002年的標準編寫
 * 下面是2002年標準中道頭數據的說明
 *
 *
 * 表3 道頭
240字節道頭
字節 描述
1-4   測線中道順序號――若一條測線有若干SEG Y文件號數遞增。強烈推薦所有類型的數據使用
5-8 SEG Y文件中道順序號――每個文件以道順序1開始。
9-12  野外原始記錄號。強烈推薦所有類型的數據使用
13-16  野外原始記錄的道號。強烈推薦所有類型的數據使用
17-20 震源點號――當在相同有效地表位置多於一個記錄時使用。建議在道頭197-202字節定義新的條目用於炮點號。
21-24 道集號(即CDP,CMP,CRP等)
25-28 道集的道數――每個道集從道號1開始
29-30 道識別碼:
-1=其他
0=未知
1=地震數據
2=死道
3=啞道
4=時斷
5=井口
6=掃描
7=定時
8=水斷
9=近場槍信號
10=遠場槍信號
11=地震壓力傳感器
12=多分量地震傳感器――垂直分量
13=多分量地震傳感器――橫向分量
14=多分量地震傳感器――縱向分量
15=旋轉多分量地震傳感器――垂直分量
16=旋轉多分量地震傳感器――切向分量
17=旋轉多分量地震傳感器――徑向分量
18=可控源反應質量
19=可控源底盤
20=可控源估計地面力
21=可控源參考
22=時間速度對
23…N=選用,(最大N=32767)
強烈推薦所有類型的數據使用
31-32 產生該道的垂直疊加道數。(1是一道,2是兩道求和,…)
33-34 產生該道的水平疊加道數。(1是一道,2是兩道求和,…)
35-36 數據用途:
1=生產
2=試驗
37-40 從震源中心點到檢波器組中心的距離(若與炮激發線方向相反取負)
41-44 檢波器組高程(所有基準以上高程爲正,以下爲負) 道頭中69-70字節的因子應用於這些數值。在二進制文件頭3255-3256字節指定單位爲英尺或米。垂直基準應通過位置數據文本段定義(見D-1節)。
45-48 震源地表高程 
49-52 震源距地表深度(正數) 
53-56 檢波器組基準高程 
57-60 震源基準高程 
61-64 震源水深 
65-68 檢波器組水深 
69-70 應用於所有在道頭41-68字節給定的真實高程和深度的因子。因子=1,+10,+100,或+1000。若爲正,因子爲乘數;若爲負,因子爲除數。
71-72 應用於所有在道頭73-88字節和181-188字節給定的真實座標值的因子。因子=1,+10,+100,或+1000。若爲正,因子爲乘數;若爲負,因子爲除數。
73-76 震源座標――X 參考座標系應通過擴展頭位置數據文本段識別(見D-1節)。
若座標單位爲弧度秒、小數度或度/分/秒(DMS),X值代表經度,Y值代表緯度。正值代表格林威治子午線以東或赤道以北,負值代表南或西。
77-80 震源座標――Y 
81-84 檢波器組座標――X 
85-88 檢波器組座標――Y 
89-90 座標單位:
1=長度(米或英尺)
2=弧度秒
3=小數度
4=度,分,秒(DMS)
注意:爲編碼±DDDMMSS 89-90字節等於±DDD*104+MM*102+SS,71-72字節設置爲1;爲編碼±DDDMMSS 89-90字節等於±DDD*106+MM*104+SS*102,71-72字節設置爲-100。
91-92 風化層速度(如二進制文件頭3255-3256字節指明的ft/s或m/s)
93-94 風化層下速度(如二進制文件頭3255-3256字節指明的ft/s或m/s)
接表3 道頭
95-96 震源處井口時間(毫秒) 毫秒錶示的時間需應用道頭215-216字節指定的因子。
97-98 檢波器組處井口時間(毫秒) 
99-100 震源的靜校正量(毫秒) 
101-102 檢波器組的校正量(毫秒) 
103-104 應用的總靜校正量(毫秒)(如沒有應用靜校正量爲零) 
105-106 延遲時間A――以毫秒錶示的240字節道識別頭的結束和時間斷點之間的時間。當時間斷點出現在頭之後,該值爲正;當時間斷點出現在頭之前,該值爲負。時間斷點是最初脈衝,它由輔助道記錄或由其他記錄系統指定。 
107-108 延遲時間B――以毫秒錶示的時間斷點到能量源起爆時間之間的時間。可正可負。 
109-110 記錄延遲時間――以毫秒錶示的能量源起爆時間到數據採樣開始記錄之間的時間。在SEG Y修訂版0中本條用來表示深水作業,如果數據記錄不從0時間開始。該條可爲負值以適應負的起始時間(即數據記錄在零時間之前,假設靜校正量應用於數據道的結果)。若某非零值(正或負)記錄在該條,它造成的影響的註釋應出現在原文文件頭。 
111-112 起始切除時間(毫秒) 
113-114 終止切除時間(毫秒) 
115-1167 該道採樣點數。強烈推薦所有類型的數據使用
117-1187 該道採樣間隔(微秒)。
一道記錄的字節數必須和寫在道頭中的採樣點數一致。對所有記錄介質都重要,但對正確處理磁盤文件中的SEG Y數據尤爲關鍵(見附錄C)。
若二進制文件頭中的3503-3504字節設置了固定長度道標誌,SEG Y文件每道的採樣間隔和採樣點數必須與二進制文件頭所記錄的值一致。若沒有設置固定長道標誌,採樣間隔和採樣點數可能每道變化。
強烈推薦所有類型的數據使用
119-120 野外儀器增益類型:
1=固定
2=二進制
3=浮點
4…N=選用
121-122 儀器增益常數(分貝)
123-124 儀器初始增益(分貝)
125-126 相關:
1=無
2=有
127-128 起始掃描頻率(赫茲)
129-130 終止掃描頻率(赫茲)
131-132 掃描長度(毫秒)
133-134 掃描類型:
1=線性
2=拋物線
3=指數
4=其他
135-136 掃描道斜坡起始長度(毫秒)
137-138 掃描道斜坡終止長度(毫秒)
139-140 斜坡類型:
1=線性
2=cos2
3=其他
141-142 假頻濾波頻率(赫茲),若使用
143-144 假頻濾波坡度(分貝/倍頻程)
145-146 陷波頻率(赫茲),若使用
147-148 陷波坡度(分貝/倍頻程)
149-150 低截頻率(赫茲),若使用
151-152 高截頻率(赫茲),若使用
153-154 低截坡度(分貝/倍頻程)
155-156 高截坡度(分貝/倍頻程)
157-158 數據記錄的年――1975年標準沒有說清應該記成2位還是4位還是兩者都用。除SGE Y修訂版0外,年份需記錄成完整的4位羅馬曆法年(即2001年應記錄爲200110(7D116))。
159-160 日(以格林尼治標準時間和通用協調時間爲基準的公元日)
161-162 時(24小時制)
163-164 分
165-166 秒
167-168 時間基準碼:
1=當地
2=格林尼治標準時間
3=其他,應在擴展原文文件頭的用戶定義文本段解釋
4=通用協調時間
169-170 道加權因子――最小有效位數定義爲2-N伏。(N=0,1,…,32767)
171-172 滾動開關位置1的檢波器組號
173-174 野外原始記錄中道號1的檢波器組號
175-176 野外原始記錄中最後一道的檢波器組號
177-178 間隔大小(滾動時甩掉的總檢波器組數)
179-180 相對測線斜坡起始或終止點的移動
1=下(或後)
2=上(或前)
181-184 該道的道集(CDP)位置X座標(應用道頭71-72字節的因子)。參考座標系應通過擴展頭位置數據文本段識別(見D-1節)
185-188 該道的道集(CDP)位置Y座標(應用道頭71-72字節的因子)。參考座標系應通過擴展頭位置數據文本段識別(見D-1節)
189-192 對於3-D疊後數據,本字段用來填縱向線號(In-line)。若每個SEG Y文件記錄一條縱向線,文件中所有道的該值應相同,並且同樣的值將記錄在二進制文件頭的3205-3206字節中。
193-196 對於3-D疊後數據,本字段用來填橫向線號(Cross-line)。它應與道頭21-24字節中的道集(CDP)號的值一致,但這並不是實例。
197-200 炮點號――這可能只應用於2-D疊後數據。
注意在此假設炮點號相對於特定道最靠近疊加(CDP)位置震源位置。如果不是這種情況,應在原文文件頭中有註釋解釋炮點實際參考點。
201-202 應用於道頭中197-200字節中炮點號的因子,以得到實際數值。若爲正,因子用作乘數;若爲負,因子用作除數;若爲零;炮點號不用於因子作用(即它是一個整數。典型的值是-10,允許炮點號小數點後有一位小數)。
203-204 道值測量單位:
-1=其他(應在數據採樣測量單位文本段描述)
0=未知
1=帕斯卡(Pa)
2=伏特(V)
3=毫伏(mV)
4=安培(A)
5=米(m)
6=米每秒(m/s)
7=米每秒二次方(m/s2)
8=牛頓(N)
9=瓦特(W)
205-210 轉換常數――該倍數用於將數據道採樣轉換成轉換單位(道頭211-212字節指定)。本常數以4字節編碼,尾數是兩互補整數(205-208字節)和2字節,十的指數冪是兩互補整數(209-210字節)(即(205-208字節)×10**(209-210字節))。
211-212 轉換單位――經乘以道頭205-210字節中的轉換常數後的數據道採樣測量單位。
-1=其他(應在數據採樣測量單位文本段36頁描述)
0=未知
1=帕斯卡(Pa)
2=伏特(V)
3=毫伏(mV)
4=安培(A)
5=米(m)
6=米每秒(m/s)
7=米每秒二次方(m/s2)
8=牛頓(N)
9=瓦特(W)
213-214 設備/道標識――與數據道關聯的單位號或設備號(即4368對應可控源號4368或20316對應2船3線16槍)。本字段允許道關聯橫跨獨立於道號的道集(道頭25-28字節)
215-216 在道頭95-114字節給出的作用於時間的因子,以得到真實的毫秒錶示的時間值。因子=1,+10,+100,+1000或+10000。若爲正,因子用作乘數;若爲負,因子用作除數。爲零設定因子爲一。
217-218 震源類型/方位――定義類型或能量源的方位。垂直項、橫向項、縱向項作爲正交座標系的三個軸。座標系軸的絕對角度方位可在面元網格定義文本段中定義(27頁)
-1到-n=其他(應在震源類型/方位文本段38頁描述)
0=未知
1=可控震源――垂直方位
2=可控震源――橫向方位
3=可控震源――縱向方位
4=衝擊源――垂直方位
5=衝擊源――橫向方位
6=衝擊源――縱向方位
7=分佈式衝擊源――垂直方位
8=分佈式衝擊源――橫向方位
9=分佈式衝擊源――縱向方位
219-224 相對震源方位的震源能量方向――正方位方向在道頭217-218字節定義。能量方向以度數長度編碼(即347.8°編碼成3478)
225-230 震源測量――描述產生道的震源效應。測量可以簡單,定量的測量如使用炸藥總重量或氣槍壓力峯值或可控源振動次數和掃描週期時間。儘管這些簡單的測量可接受,但最好使用真實的能量或工作測量單位。
本常數編碼成4字節,尾數爲兩互補整數(225-228字節)和2字節,十的指數冪是兩互補整數(209-230字節)(即(225-228字節)×10**(229-230字節))。
231-232 震源測量單位――用於震源測量、道頭225-230字節的單位。
-1=其他(應在震源測量單位文本段39頁描述)
0=未知
1=焦耳(J)
2=千瓦(kW)
3=帕斯卡(Pa)
4=巴(Bar)
4=巴-米(Bar-m)
5=牛頓(N)
6=千克(kg)
233-240 未賦值――爲任選信息預留

 * @author dingyi
 *
 */

public class SegyTrace {
 // 1-4 測線中道順序號――若一條測線有若干SEG Y文件號數遞增。強烈推薦所有類型的數據使用
 int trace_sequence_number_within_line;

 // 5-8 SEG Y文件中道順序號――每個文件以道順序1開始。
 int trace_sequence_number_within_reel;

 // 9-12 野外原始記錄號。強烈推薦所有類型的數據使用
 int original_field_record_number;

 // 13-16 野外原始記錄的道號。強烈推薦所有類型的數據使用
 int trace_sequence_number_within_original_field_record;

 // 17-20 震源點號――當在相同有效地表位置多於一個記錄時使用。
 // 建議在道頭197-202字節定義新的條目用於炮點號。
 int energy_source_point_number;

 // 21-24 道集號(即CDP,CMP,CRP等)
 int cdp_ensemble_number;

 // 25-28 道集的道數――每個道集從道號1開始
 int trace_sequence_number_within_cdp_ensemble;

 /**
  * 29-30 道識別碼: -1=其他 0=未知 1=地震數據 2=死道 3=啞道 4=時斷 5=井口 6=掃描 7=定時 8=水斷 9=近場槍信號
  * 10=遠場槍信號 11=地震壓力傳感器 12=多分量地震傳感器――垂直分量 13=多分量地震傳感器――橫向分量 14=多分量地震傳感器――縱向分量
  * 15=旋轉多分量地震傳感器――垂直分量 16=旋轉多分量地震傳感器――切向分量 17=旋轉多分量地震傳感器――徑向分量 18=可控源反應質量
  * 19=可控源底盤 20=可控源估計地面力 21=可控源參考 22=時間速度對 23…N=選用,(最大N=32767) 強烈推薦所有類型的數據使用
  * *
  */
 short trace_identification_code;// 道識別碼

 // 31-32 產生該道的垂直疊加道數。(1是一道,2是兩道求和,…)
 short number_of_vertically_summed_traces_yielding_this_trace;

 // 33-34 產生該道的水平疊加道數。(1是一道,2是兩道求和,…)
 short number_of_horizontally_stacked_traced_yielding_this_trace;

 /**
  * 35-36 數據用途: 1=生產 2=試驗*
  */
 short data_use;

 // 37-40 從震源中心點到檢波器組中心的距離(若與炮激發線方向相反取負)
 int distance_from_source_point_to_receiver_group;

 // 41-44 檢波器組高程(所有基準以上高程爲正,以下爲負)
 // 道頭中69-70字節的因子應用於這些數值。
 //在二進制文件頭3255-3256字節指定單位爲英尺或米。
 //垂直基準應通過位置數據文本段定義(見D-1節)。
 int receiver_group_elevation;

 // 45-48 震源地表高程
 int surface_elevation_at_source;

 // 49-52 震源距地表深度(正數)
 int source_depth_below_surface;

 // 53-56 檢波器組基準高程
 int datum_elevation_at_receiver_group;

 // 57-60 震源基準高程
 int datum_elevation_at_source;

 // 61-64 震源水深
 int water_depth_at_source;
 // 65-68 檢波器組水深
 int water_depth_at_receiver_group;

 // 69-70
 // 應用於所有在道頭41-68字節給定的真實高程和深度的因子。因子=1,+10,+100,或+1000。若爲正,因子爲乘數;若爲負,因子爲除數。
 short scalar_for_elevations_and_depths;

 // 71-72
 // 應用於所有在道頭73-88字節和181-188字節給定的真實座標值的因子。因子=1,+10,+100,或+1000。若爲正,因子爲乘數;若爲負,因子爲除數。
 short scalar_for_coordinates;

 /**
  * 73-76 震源座標――X 參考座標系應通過擴展頭位置數據文本段識別(見D-1節)。
  * 若座標單位爲弧度秒、小數度或度/分/秒(DMS),X值代表經度,
  * Y值代表緯度。
  * 正值代表格林威治子午線以東或赤道以北,
  * 負值代表南或西。
  */
 int x_source_coordinate;
 // 77-80 震源座標――Y
 int y_source_coordinate;

 // 81-84 檢波器組座標――X
 int x_receiver_group_coordinate;

 // 85-88 檢波器組座標――Y
 int y_receiver_group_coordinate;

 /**
  * 89-90 座標單位: 1=長度(米或英尺) 2=弧度秒 3=小數度 4=度,分,秒(DMS) 注意:爲編碼±DDDMMSS
  * 89-90字節等於±DDD*104+MM*102+SS,71-72字節設置爲1;爲編碼±DDDMMSS
  * 89-90字節等於±DDD*106+MM*104+SS*102,71-72字節設置爲-100。
  */
 short coordinate_units;

 // 91-92 風化層速度(如二進制文件頭3255-3256字節指明的ft/s或m/s)
 short weathering_velocity;

 // 93-94 風化層下速度(如二進制文件頭3255-3256字節指明的ft/s或m/s)
 short subweathering_velocity;

 // 95-96 震源處井口時間(毫秒) 毫秒錶示的時間需應用道頭215-216字節指定的因子。
 short uphole_time_at_source;

 // 97-98 檢波器組處井口時間(毫秒)
 short uphole_time_at_group;

 // 99-100 震源的靜校正量(毫秒)
 short source_static_correction;

 // 101-102 檢波器組的校正量(毫秒)
 short group_static_correction;

 // 103-104 應用的總靜校正量(毫秒)(如沒有應用靜校正量爲零)
 short total_static_applied;

 // 105-106
 // 延遲時間A――以毫秒錶示的240字節道識別頭的結束和時間斷點之間的時間。當時間斷點出現在頭之後,該值爲正;當時間斷點出現在頭之前,該值爲負。時間斷點是最初脈衝,它由輔助道記錄或由其他記錄系統指定。
 short lag_time_a;

 // 107-108 延遲時間B――以毫秒錶示的時間斷點到能量源起爆時間之間的時間。可正可負。
 short lag_time_b;

 // 109-110 記錄延遲時間――以毫秒錶示的能量源起爆時間到數據採樣開始記錄之間的時間。在SEG
 // Y修訂版0中本條用來表示深水作業,如果數據記錄不從0時間開始。該條可爲負值以適應負的起始時間(即數據記錄在零時間之前,假設靜校正量應用於數據道的結果)。若某非零值(正或負)記錄在該條,它造成的影響的註釋應出現在原文文件頭。
 short delay_according_time;

 // 111-112 起始切除時間(毫秒)
 short brute_time_start;

 // 113-114 終止切除時間(毫秒)
 short mute_time_end;

 // 115-1167 該道採樣點數。強烈推薦所有類型的數據使用
 short samples_in_this_trace;

 // 117-1187 該道採樣間隔(微秒)。
 // 一道記錄的字節數必須和寫在道頭中的採樣點數一致。對所有記錄介質都重要,但對正確處理磁盤文件中的SEG Y數據尤爲關鍵(見附錄C)。
 // 若二進制文件頭中的3503-3504字節設置了固定長度道標誌,SEG
 // Y文件每道的採樣間隔和採樣點數必須與二進制文件頭所記錄的值一致。若沒有設置固定長道標誌,採樣間隔和採樣點數可能每道變化。
 short sample_intervall;

 /**
  * 119-120 野外儀器增益類型: 1=固定 2=二進制 3=浮點 4…N=選用
  */
 short gain_type_instruments;

 // 121-122 儀器增益常數(分貝)
 short instrument_gain_para;

 // 123-124 儀器初始增益(分貝)
 short instrument_initial_gain_para;

 // 125-126 相關: 1=無 2=有
 short has_relation;

 // 127-128 起始掃描頻率(赫茲)
 short freq_start;

 // 129-130 終止掃描頻率(赫茲)
 short freq_end;

 // 131-132 掃描長度(毫秒)
 short sweep_length;

 // 133-134 掃描類型: 1=線性 2=拋物線 3=指數 4=其他
 short sweep_type;

 // 135-136 掃描道斜坡起始長度(毫秒)
 short sweep_start_length;

 // 137-138 掃描道斜坡終止長度(毫秒)
 short sweep_end_length;

 // 139-140 斜坡類型: 1=線性 2=cos2 3=其他
 short sweep_gradient_type;

 // 141-142 假頻濾波頻率(赫茲),若使用
 short fake_filter_freq;

 // _143-144 假頻濾波坡度(分貝/倍頻程)
 short fake_filter_gradient;

 // 145-146 陷波頻率(赫茲),若使用
 short trap_freq;

 // 147-148 陷波坡度(分貝/倍頻程)
 short trap_gradient;

 // 149-150 低截頻率(赫茲),若使用
 short low_freq;

 // 151-152 高截頻率(赫茲),若使用
 short high_freq;

 // 153-154 低截坡度(分貝/倍頻程)
 short low_gradient;

 // 155-156 高截坡度(分貝/倍頻程)
 short hight_gradient;

 // 157-158 數據記錄的年――1975年標準沒有說清應該記成2位還是4位還是兩者都用。
 // 除SGE Y修訂版0外,年份需記錄成完整的4位羅馬曆法年(即2001年應記錄爲2001(7D116))。
 short year;

 // 159-160 日(以格林尼治標準時間和通用協調時間爲基準的公元日)
 short day;

 // 161-162 時(24小時制)
 short hour;

 // 163-164 分
 short minute;

 // 165-166 秒
 short second;

 // 167-168 時間基準碼:
 /**
  * 1=當地 2=格林尼治標準時間 3=其他,應在擴展原文文件頭的用戶定義文本段解釋 4=通用協調時間
  */
 short datum_time;

 // 169-170 道加權因子――最小有效位數定義爲2-N伏。(N=0,1,…,32767)
 short trace_factor;

 // 171-172 滾動開關位置1的檢波器組號
 short switch_1_receiver_group;

 // 173-174 野外原始記錄中道號1的檢波器組號
 short switch_1_filed_receiver_group;

 // 175-176 野外原始記錄中最後一道的檢波器組號
 short last_trace_receiver_group;

 // 177-178 間隔大小(滾動時甩掉的總檢波器組數)
 short interval;

 // 179-180 相對測線斜坡起始或終止點的移動 1=下(或後) 2=上(或前)
 short translate_start_or_end;

 /**
  * 81-184 該道的道集(CDP)位置X座標(應用道頭71-72字節的因子)。 參考座標系應通過擴展頭位置數據文本段識別(見D-1節)
  */
 int cdp_x;

 /**
  * 185-188 該道的道集(CDP)位置Y座標(應用道頭71-72字節的因子)。 參考座標系應通過擴展頭位置數據文本段識別(見D-1節)
  */
 int cdp_y;
 /**
  * 189-192 對於3-D疊後數據,本字段用來填縱向線號(In-line)。 若每個SEG Y文件記錄一條縱向線,文件中所有道的該值應相同,
  * 並且同樣的值將記錄在二進制文件頭的3205-3206字節中。
  */
 int in_line_num;

 /**
  * 193-196 對於3-D疊後數據,本字段用來填橫向線號(Cross-line)。
  * 它應與道頭21-24字節中的道集(CDP)號的值一致,但這並不是實例。
  */
 int cross_line_num;

 /**
  * 197-200 炮點號――這可能只應用於2-D疊後數據。
  * 注意在此假設炮點號相對於特定道最靠近疊加(CDP)位置震源位置。如果不是這種情況,應在原文文件頭中有註釋解釋炮點實際參考點。
  */
 int source_power_num;

 /**
  * 201-202 應用於道頭中197-200字節中炮點號的因子,以得到實際數值。 若爲正,因子用作乘數;若爲負,因子用作除數;
  * 若爲零;炮點號不用於因子作用(即它是一個整數。典型的值是-10, 允許炮點號小數點後有一位小數)。
  */
 short source_power_factor;
 /**
  * 203-204 道值測量單位: -1=其他(應在數據採樣測量單位文本段描述) 0=未知 1=帕斯卡(Pa) 2=伏特(V) 3=毫伏(mV)
  * 4=安培(A) 5=米(m) 6=米每秒(m/s) 7=米每秒二次方(m/s2) 8=牛頓(N) 9=瓦特(W)
  */
 short trace_measure_unit;

 /**
  * 205-210 轉換常數――該倍數用於將數據道採樣轉換成轉換單位 (道頭211-212字節指定)。
  * 本常數以4字節編碼,尾數是兩互補整數(205-208字節)和2字節, 十的指數冪是兩互補整數(209-210字節)
  * (即(205-208字節)×10**(209-210字節))。
  */
 long trans_const_factor;

 /**
  * 211-212 轉換單位――經乘以道頭205-210字節中的轉換常數後的 數據道採樣測量單位。 -1=其他(應在數據採樣測量單位文本段36頁描述)
  * 0=未知 1=帕斯卡(Pa) 2=伏特(V) 3=毫伏(mV) 4=安培(A) 5=米(m) 6=米每秒(m/s) 7=米每秒二次方(m/s2)
  * 8=牛頓(N) 9=瓦特(W)
  */
 short trans_unit;

 /**
  * 213-214 設備/道標識――與數據道關聯的單位號或設備號 (即4368對應可控源號4368或20316對應2船3線16槍)。
  * 本字段允許道關聯橫跨獨立於道號的道集(道頭25-28字節)
  */
 short instrument_trace_id;

 /**
  * 215-216 在道頭95-114字節給出的作用於時間的因子, 以得到真實的毫秒錶示的時間值。
  * 因子=1,+10,+100,+1000或+10000。 若爲正,因子用作乘數;若爲負,因子用作除數。爲零設定因子爲一。
  */
 short time_factor;

 /*
  * 217-218
  * 震源類型/方位――定義類型或能量源的方位。垂直項、橫向項、縱向項作爲正交座標系的三個軸。座標系軸的絕對角度方位可在面元網格定義文本段中定義
  * (27頁) -1到-n=其他(應在震源類型/方位文本段38頁描述) 0=未知 1=可控震源――垂直方位 2=可控震源――橫向方位
  * 3=可控震源――縱向方位 4=衝擊源――垂直方位 5=衝擊源――橫向方位 6=衝擊源――縱向方位 7=分佈式衝擊源――垂直方位
  * 8=分佈式衝擊源――橫向方位 9=分佈式衝擊源――縱向方位
  */
 short source_type_or_direction;

 /**
  * 219-224 相對震源方位的震源能量方向―― 正方位方向在道頭217-218字節定義。 能量方向以度數長度編碼(即347.8°編碼成3478)
  */
 long source_power_dirction;

 /*
  * 225-230 震源測量――描述產生道的震源效應。 測量可以簡單,定量的測量如使用炸藥總重量或氣槍壓力峯值 或可控源振動次數和掃描週期時間。
  * 儘管這些簡單的測量可接受,但最好使用真實的能量或工作測量單位。 本常數編碼成4字節,尾數爲兩互補整數(225-228字節)和2字節,
  * 十的指數冪是兩互補整數(209-230字節)(即(225-228字節)×10**(229-230字節))。
  */
 long source_power_measure;

 /*
  * 231-232 震源測量單位――用於震源測量、道頭225-230字節的單位。 -1=其他(應在震源測量單位文本段39頁描述) 0=未知
  * 1=焦耳(J) 2=千瓦(kW) 3=帕斯卡(Pa) 4=巴(Bar) 4=巴-米(Bar-m) 5=牛頓(N) 6=千克(kg)
  */
 short source_power_measure_unit;//

 // 233-240 未賦值――爲任選信息預留

 public SegyTrace(byte[] b) {
  int i = 0;
  trace_sequence_number_within_line = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 4;
  trace_sequence_number_within_reel = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 8;
  original_field_record_number = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);

  i = 12;
  trace_sequence_number_within_original_field_record = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);

  i = 16;
  energy_source_point_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 20;
  cdp_ensemble_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 24;
  trace_sequence_number_within_cdp_ensemble = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 28;
  trace_identification_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 30;
  number_of_vertically_summed_traces_yielding_this_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 32;
  number_of_horizontally_stacked_traced_yielding_this_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 34;
  data_use = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 36;
  distance_from_source_point_to_receiver_group = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 40;
  receiver_group_elevation = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 44;
  surface_elevation_at_source = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 48;
  source_depth_below_surface = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 52;
  datum_elevation_at_receiver_group = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 56;
  datum_elevation_at_source = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 60;
  water_depth_at_source = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 64;
  water_depth_at_receiver_group = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 68;
  scalar_for_elevations_and_depths = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 70;
  scalar_for_coordinates = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 72;
  x_source_coordinate = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 76;
  y_source_coordinate = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 80;
  x_receiver_group_coordinate = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 84;
  y_receiver_group_coordinate = b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
    | (b[i] << 24 & 0xff000000);
  i = 88;
  coordinate_units = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));

  i = 90;
  weathering_velocity = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 92;
  subweathering_velocity = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 94;
  uphole_time_at_source = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 96;
  uphole_time_at_group = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 98;
  source_static_correction = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));

  i = 100;
  group_static_correction = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 102;
  total_static_applied = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 104;
  lag_time_a = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 106;
  lag_time_b = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 108;
  delay_according_time = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));

  i = 110;
  brute_time_start = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 112;
  mute_time_end = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 114;
  samples_in_this_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 116;
  sample_intervall = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 118;
  gain_type_instruments = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));

  i = 120;
  instrument_gain_para = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 122;
  instrument_initial_gain_para = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 124;
  has_relation = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 126;
  freq_start = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 128;
  freq_end = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 130;
  sweep_length = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 132;
  sweep_type = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 134;
  sweep_start_length = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 136;
  sweep_end_length = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 138;
  sweep_gradient_type = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 140;
  fake_filter_freq = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 142;
  fake_filter_gradient = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 144;
  trap_freq = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 146;
  trap_gradient = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 148;
  low_freq = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 150;
  high_freq = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 152;
  low_gradient = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 154;
  hight_gradient = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 156;
  year = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 158;
  day = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 160;
  hour = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 162;
  minute = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 164;
  second = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 166;
  datum_time = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 168;
  trace_factor = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 170;
  switch_1_receiver_group = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 172;
  switch_1_filed_receiver_group = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 174;
  last_trace_receiver_group = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 176;
  interval = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 178;
  translate_start_or_end = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 180;
  cdp_x = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 184;
  cdp_y = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 188;
  in_line_num = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 192;
  cross_line_num = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 196;
  source_power_num = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
    | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
  i = 200;
  source_power_factor = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 202;
  trace_measure_unit = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 204;
  trans_const_factor = (long) ((b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000)) * Math
    .pow(10, b[i + 5] | (b[i + 4] << 8 & 0xff00)));
  i = 210;
  trans_unit = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 212;
  instrument_trace_id = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
  i = 214;
  time_factor = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));

  i = 216;
  source_type_or_direction = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));

  i = 218;
  source_power_dirction = b[i + 5] | (b[i + 4] << 8 & 0xff00)
    | (b[i + 3] << 16 & 0xff0000) | (b[i + 2] << 24 & 0xff000000)
    | (b[i + 1] << 24 & 0xff000000) << 8
    | (b[i] << 24 & 0xff000000) << 16;
  i = 224;
  source_power_measure = (long) ((b[i + 3] & 0xff
    | (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000)) * Math
    .pow(10, b[i + 5] | (b[i + 4] << 8 & 0xff00)));
  i = 230;
  source_power_measure_unit = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));//

 }

 double[] data;// 存儲道值
 
 /**
  * 按照IBM浮點數的方式讀取數據,對應帶頭中的數據類型1
  * @param buf
  * @return
  * @throws SegyFileFormatException
  */
 public double[] readDataInIBMFormat(byte[] buf) throws SegyFileFormatException {
  data = new double[samples_in_this_trace];

  for (int i = 0; i < samples_in_this_trace; i++) {
   // 按照字節位序一致的方式解讀
   int sign = (buf[4 * i] >> 7) & 0x01;
   int exp = buf[4 * i] & 0x7f;
   exp = exp - 64;
   int frac = ((buf[4 * i + 1] << 16) & 0x00ff0000)
     | ((buf[4 * i + 2] << 8) & 0x0000ff00)
     | (buf[4 * i + 3] & 0x000000ff) & 0x00ffffff;
   if (frac == 0) {
    data[i] = 0;
    continue;
   }
   double result = (1 - 2 * sign) * frac * Math.pow(2, 4 * exp - 24);

   // 按照字節位序相反的方式解讀,事實證明這樣解讀是不對的。
   //
   // byte b1=inverseBit(buf[4*i]);
   // byte b2=inverseBit(buf[4*i+1]);
   // byte b3=inverseBit(buf[4*i+2]);
   // byte b4=inverseBit(buf[4*i+3]);
   // int sign=(b1>>7 ) & 0x01;
   //
   // int exp=b1 & 0x7f;
   // exp=exp-64;
   // int frac=((b2<<16) & 0x00ff0000) |(( b3 <<8) & 0x0000ff00) | (b4
   // & 0x000000ff) & 0x00ffffff;
   // if(frac==0 ){
   // data[i]=0;
   // continue;
   // }
   // double result=(1-2*sign)*frac/Math.pow(2,24)*Math.pow(16, exp);

   data[i] = result;

  }

  return data;
 }

 // 翻轉字節序
 private static byte inverseBit(byte b) {
  String temp = Integer.toBinaryString(b & 0xff);
  if (temp.length() >= 8) {
   temp = temp.substring(temp.length() - 8);
  } else {
   // 前面補零
   int len = temp.length();
   for (int i = 0; i < 8 - len; i++) {
    temp = "0" + temp;
   }
  }
  System.out.println("轉換前:" + temp);
  // 把它翻轉
  String s = "";
  for (int i = temp.length() - 1; i >= 0; i--) {
   s = s + temp.charAt(i);
  }
  System.out.println("轉換後:" + s);
  return (byte) Integer.parseInt(s, 2);
 }

 public static void main(String[] args) {
  System.out.println(Integer.toBinaryString(inverseBit((byte) -128)));
 }
 /**
  * 得到震源地表高程
  * 計算方法: (值-基準值)再乘或者除 高程因子,參看規範
  * @return
  */
 public int getSurface_elevation_at_source() {
  if(scalar_for_elevations_and_depths>=0){
   return (surface_elevation_at_source-datum_elevation_at_source)*scalar_for_elevations_and_depths;
  }else
   return -(surface_elevation_at_source-datum_elevation_at_source)/scalar_for_elevations_and_depths;
 }
 /**
  * 得到檢波器地表高程
  * 計算方法: (值-基準值)再乘或者除 高程因子,參看規範
  * @return
  */
 public int getReceiver_group_elevation() {
  if(scalar_for_elevations_and_depths>=0){
   return (receiver_group_elevation-datum_elevation_at_receiver_group)*scalar_for_elevations_and_depths;
  }else
   return -(receiver_group_elevation-datum_elevation_at_receiver_group)/scalar_for_elevations_and_depths;
 }
}
/**
 * D-1
 *
 * 表5 位置數據文本段
文本段頭和關鍵字 格式 註釋
((SEG: 位置數據版本1.0)) 文本 文本段名稱
以下關鍵字應用於所有參考座標系(CRS)
CRS類型= 源於列舉表:投影、地理、複合 投影=地圖網格
地理=緯度、經度和3-DCRS情況下附加的橢圓高度
複合=準三維座標系,由2D地理或帶與重力相關的高度系統的投影CRS
CRS名稱= 文本 參考座標系名稱
大地基準名稱= 文本 大地基準名稱
本初子午線名稱= 文本 若不是“格林威治”,強制
注意:多數,但不是所有,參考座標系用格林威治作本初子午線(PM)
PM格林威治經度= 實數 CRS的本初子午線相對於格林威治子午線的經度,當在格林威治的東邊爲正。若本初子午線名稱=“格林威治”是不需要
PM格林威治經度單位名稱= 文本 若本初子午線名稱=“格林威治”是不需要
橢圓名稱= 文本 
橢圓半主軸= 實數 
半主軸單位名稱= 文本 
橢圓扁率倒數= 實數 
座標軸1名稱= 文本 道頭73-76,81-84和181-184字節的座標軸(CS)的名稱或縮寫。例如東,X,E,或經度
CS軸1方位= 文本 軸1的正方向。例如:“東”或“北”
座標軸2名稱= 文本 道頭77-80,85-88和185-188字節的座標軸(CS)的名稱或縮寫。例如北,Y,N,或緯度
CS軸2方位= 文本 軸2的正方向。例如:“北”或“東”
垂直基準名稱= 文本 垂直基準名稱。若使用橢圓高度不需要(多數高度和深度是與重力相關的,而不是橢圓)
座標軸3名稱= 文本 道頭41-68字節的高程和深度的座標軸的名稱或縮寫。例如:重力相關高度,橢圓高度
CS軸3方位= 文本 軸3的正方向。例如:“上”
以下關鍵字是投影座標參考系額外需要的,它是當在字節89-90指明座標單位是長度或當面元網格定義文本段或數據地理範圍擴展文本段或覆蓋區域文本段包含在擴展文件頭中時
投影區名稱= 文本 
投影方法名稱= 文本 例如:“橫向墨卡託”,“朗伯正交圓錐投影(1SP)”,“朗伯正交圓錐投影(2SP)”。
數字和參數類型決定於地圖投影方法。對於橫向墨卡託和朗伯正交圓錐投影(1SP),需要的5個參數是:
• 原始自然緯度
• 原始自然經度
• 原始自然比例因子
• 東偏
• 北偏
地圖投影方法爲朗伯正交圓錐投影(2SP)需要的6個參數見下面的示例
投影參數1名稱= 文本 
投影參數1數值= 實數 
投影單位1單位名稱= 文本 
投影參數2名稱= 文本 
投影參數2數值= 實數 
投影單位2單位名稱= 文本 
…   
投影參數7名稱= 文本 
投影參數7數值= 實數 
投影單位7單位名稱= 文本 
D-1.2. 位置數據文本段示例
((SEG: 位置數據版本1.0))
CRS類型=                                 投影
CRS名稱=                                 NAD27/德克薩斯南中心
大地基準名稱=                            北美1927基準
橢圓名稱=                                克拉克1866
橢圓半主軸=                              6378206.4
半主軸單位名稱=                          米
橢圓扁率倒數=                            294.9786982
座標軸1名稱=                             Y
CS軸1方位=                               北
座標軸2名稱=                             X
CS軸2方位=                               東
投影區名稱=                              得克薩斯CS27南中心區
投影方法名稱=                            朗伯正交圓錐投影(2SP)
 
 
投影參數1名稱=                           原始緯度偏差
投影參數1數值=                           27.5
投影單位1單位名稱=                       DDD.MMSSsss
投影參數2名稱=                           原始經度偏差
投影參數2數值=                           -99
投影單位2單位名稱=                       度
投影參數3名稱=                           第一標準平行緯度
投影參數3數值=                           28.23
投影單位3單位名稱=                       DDD.MMSSsss
投影參數4名稱=                           第二標準平行緯度
投影參數4數值=                           30.17
投影單位4單位名稱=                       DDD.MMSSsss
投影參數5名稱=                           原始東偏
投影參數5數值=                           2000000.0
投影單位5單位名稱=                       US測量步
投影參數6名稱=                           原始北偏
投影參數6數值=                           0.0
投影單位6單位名稱=                       US測量步

 *
 *
 */

———————————————vtk顯示類,用於測試和現實segy讀取的結果—————————————————————————————————

package org.sinoprobe.segy;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.UnsupportedEncodingException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import vtk.vtkActor;
import vtk.vtkAxesActor;
import vtk.vtkBandedPolyDataContourFilter;
import vtk.vtkCamera;
import vtk.vtkCanvas;
import vtk.vtkCellArray;
import vtk.vtkConeSource;
import vtk.vtkDEMReader;
import vtk.vtkDoubleArray;
import vtk.vtkImageDataGeometryFilter;
import vtk.vtkImageShrink3D;
import vtk.vtkLODActor;
import vtk.vtkLookupTable;
import vtk.vtkNativeLibrary;
import vtk.vtkOrientationMarkerWidget;
import vtk.vtkPanel;
import vtk.vtkPoints;
import vtk.vtkPolyData;
import vtk.vtkPolyDataMapper;
import vtk.vtkPolyDataNormals;
import vtk.vtkRenderWindow;
import vtk.vtkRenderWindowInteractor;
import vtk.vtkRenderWindowPanel;
import vtk.vtkRenderer;
import vtk.vtkSTLReader;
import vtk.vtkShrinkPolyData;
import vtk.vtkWarpScalar;

/**
 * An application that displays a 3D cone. The button allow to close the
 * application
 */
public class SimpleVTK2 extends JPanel implements ActionListener {
    private static final long serialVersionUID = 1L;
    private vtkCanvas renPanel;
    private JButton exitButton;

    // -----------------------------------------------------------------
    // Load VTK library and print which library was not properly loaded
    static {
        if (!vtkNativeLibrary.LoadAllNativeLibraries()) {
            for (vtkNativeLibrary lib : vtkNativeLibrary.values()) {
                if (!lib.IsLoaded()) {
                    System.out.println(lib.GetLibraryName() + " not loaded");
                }
            }
        }
        vtkNativeLibrary.DisableOutputWindow(null);
    }
   
    private vtkPolyData getGridPolyData(SegyReader segy){
     int traceNums=segy.getTraceList().size();
     double interval=segy.getReelHdr().sample_data_interval_ms/1000.0;//原來是微秒,轉化爲毫秒
     int sampleNums=segy.getReelHdr().samples_per_trace;
     double left=-1000;
     double top=segy.getTraceList().get(0).getReceiver_group_elevation();//得到第一組的高程
     int space=40;//缺省定義的道間距
     int vSpace=2;
     double[] minMax=segy.getMinMaxValue();
     double dist=minMax[1]-minMax[0];
     System.out.println("測量震幅的最大值:"+minMax[1]+"   最小值:"+minMax[0]+"   兩者差值:"+dist);
     //缺省認爲最大最小值跨越 ? 個道間距
     double amplitudeFactor=8*space/dist;
     System.out.println("震幅計算因子:"+amplitudeFactor);
  //此處以5:1的比例抽樣,以加快速度,另外避免機器內存溢出
     //如果爲1,則依照原始數據繪圖;
     //爲了避免偏振效應,需要按照奇數進行抽樣,所以,不能爲偶數
     int  sampleFactor=5;
     
     vtkPolyData rtn=new vtkPolyData();
     //生成所有的點
  vtkPoints points=new vtkPoints();
  //多邊形
  vtkCellArray cellArry=new vtkCellArray();
  //標量值
  vtkDoubleArray scalars=new vtkDoubleArray();

     //開始構建數據
     for(int i=0;i<traceNums;i++){
      double x=left+i*space;
      SegyTrace trace=segy.getTraceList().get(i);

      cellArry.InsertNextCell(trace.samples_in_this_trace/sampleFactor + ((trace.samples_in_this_trace %sampleFactor >0) ? 1:0));
      for(int j=0;j<trace.samples_in_this_trace;j=j+sampleFactor){
       double z=top+j*vSpace;
       int id=points.InsertNextPoint(x+trace.data[j]*amplitudeFactor,0,z);
       scalars.InsertNextTuple1(trace.data[j]);
       cellArry.InsertCellPoint(id);
      }
     }
     //設置點
     rtn.SetPoints(points);
     //設置爲線
     rtn.SetLines(cellArry);
     rtn.GetPointData().SetScalars(scalars);
     System.out.println("vtk數據構造完成,開始顯示");
     return rtn;
    }
   
    // -----------------------------------------------------------------
    public SimpleVTK2(SegyReader segy) {
        super(new BorderLayout());

  // build VTK Pipeline
  //
  renPanel = new vtkRenderWindowPanel();
  
  vtkPolyData seg=getGridPolyData(segy);
  

  vtkPolyDataMapper demMapper = new vtkPolyDataMapper();
  demMapper.SetInput(seg);
  demMapper.ScalarVisibilityOff();
  
  vtkActor demActor = new vtkActor();
  demActor.SetMapper(demMapper);
  demActor.GetProperty().SetColor(0,0, 0);

  
  
  
  // # Create the RenderWindow, Renderer and both Actors
  vtkRenderer ren = renPanel.GetRenderer();
  vtkRenderWindowInteractor iren = renPanel.getRenderWindowInteractor();

  // # Add the actors to the renderer, set the background and size
  ren.AddActor(demActor);

  // 添加座標系
  vtkAxesActor axes = new vtkAxesActor();
  vtkOrientationMarkerWidget widget = new vtkOrientationMarkerWidget();
  widget.SetOutlineColor(0.9300, 0.5700, 0.1300);
  widget.SetOrientationMarker(axes);
  widget.SetInteractor(iren);
  widget.SetViewport(0.7, 0.7, 1, 1);
  widget.SetEnabled(1);
  widget.InteractiveOff();

  ren.SetBackground(1, 1, 1);

  vtkCamera cam = new vtkCamera();
  cam.SetPosition(0, 1000, 0);
  cam.SetFocalPoint(0, 0, 0);
  cam.SetViewUp(0, 0, -1);
  ren.SetActiveCamera(cam);
  ren.ResetCamera();
  cam.Zoom(2);

  add(renPanel, BorderLayout.CENTER);
    }

    /** An ActionListener that listens to the button. */
    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(exitButton)) {
            System.exit(0);
        }
    }

}

______________________________代碼上傳到此結束__________________________________________________________________________

幾句題外話:

 

1,Segy數據讀取類裏只實現了IBM浮點數一種轉換辦法,其他的還沒弄完,等弄完了再分享給大家;

2,在進行數據轉換的時候,儘量多用移位和位操作,這樣比計算加減乘除快很多;

3,對於增益、修正等參數,還沒有做,只是對原始測量數據做了個顯示;

4,vtk顯示效果還不錯,用java來使用vtk,是個好選擇,建議大家多嘗試。誰說java不能做這種大規模數據處理和運算的呢?誰說Java的顯示效果不如c++呢?偶私下做了對比,這部分的執行效果,與網上下載的c++所寫的segy顯示的程序,執行速度要快很多,偶嘗試了一個30M的單炮文件和100M左右的疊加後的文件,執行速度比c++的那個vsegyview快不少。而且,vtk可以進行任意的放大縮小漫遊,以及三維轉換,不是一個靜態圖。

5,配色和參數配置上,效果不理想,專業人員看了可能覺得差距太大,這部分有待於完善。歡迎大家交流。謝謝!

 

附上兩張成圖的效果:

 

上面是疊加後的

下面是單炮記錄

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章