05、解剖CEL文件各版本格式和讀取方法(非R語言)


  相比DAT文件,網絡上更支持CEL級別的文件。CEL已經把DAT圖像轉換成數據了,而且CELDAT所占空間小得多。介紹一下CEL文件的格式,CEL文件有文本文件(TextCelFile,版本3)、BinaryCelFile(二進制文件,版本4)、GenericCelFile(普通文件,版本1)三種。

 

1)版本3

早期的CEL文件是版本3的,因為是文本文件,所以直接用記事本打開就可以看到里面的內容了,如下是GSM2899.CEL

 

[CEL]

Version=3

 

[HEADER]

Cols=640

Rows=640

……

DatHeader=[5..46118]  AFRGV01031201:CLS=4733 RWS=4733 XIN=3  YIN=3  VE=17        2.0 03/12/ 1 17:16:25     GridVerify=None  HG_U95Av2.1sq                  6

……

CellHeader=X Y MEAN STDV NPIXELS

  0   0 278.0 95.3  25

  1   0 22909.3 5244.4  20

  2   0 390.0 121.0  25

  3   0 22530.0 5102.5  25

  ……

  638 639 20835.5 3531.1  20

  639 639 292.0 85.2  25

 

可以看到Version=3,列數Cols和行數Rows都是640。可以發現DatHeader里有很多的 ,它起到了分割字符串的作用(這是我第一次在C語言源碼里看到 這樣的亂碼),把“DatHeader=”后面的部分分割成若干部分,然后找出以“.1sq”結尾的那部分,即“HG_U95Av2.1sq”,再把“.1sq”去掉,就成功讀取出芯片型號HG_U95Av2了。CellHeader=X Y MEAN STDV NPIXELS中的XY指的就是探針(特征)的X坐標和Y坐標,MEAN指探針的強度,STDV是方差,NPIXELS指用多少個像素來計算MEANSTDV。每一行是一個探針(特征)的數據,這是一個640*640的陣列,所以X會從0變化到(640-1),以此循環640次,Y也從0變化到(640-1),不過每個數要重復640次。這樣,就剛好有640*640行了。我們所要用到的數據只是MEAN那一列而已,不需要STDVNPIXELS,而XY可以經過推算得出。這樣,我們就可以理解為:坐標為(0,0)的探針強度為278.0,坐標為(1,0)的探針強度為22909.3,坐標為(2,0)的探針強度為390.0……

 

2)版本4

后來出現了版本4CEL文件,它們是二進制文件,直接用記事本打開會看到很多的亂碼。可以用CellFileConversionTool.exe工具進行版本3和版本4的格式轉換。把版本3轉換成版本4后,文件就小多了,因為已經去掉了XY這兩列的數據。該版本采用了小端字節序,下面列舉了不同數據類型的不同讀取方法:

 

Integer

 

若用Java讀取整型數據:

 

如:FileInputStream fin=new FileInputStream("CEL文件的路徑");

DataInputStream din=new DataInputStream(fin);

……

/*先讀取出4個字節*/

int[] byteDataInt=new int[4];

for (int i=0;i<4;i++)        

byteDataInt[i]=din.read();

 

/*移位,第(i-1)個字節右移i*8個字節*/

for (int i=0;i<4;i++)

byteDataInt[i]=byteDataInt[i]<<8*i; 

 

/*再進行 運算*/

int result=byteDataInt[0]|byteDataInt[1]|byteDataInt[2]|byteDataInt[3];

……

 

若用C把完成以上的工作,就方便多了:

 

如:FILE *infile = fopen("CEL文件的路徑", "rb")) ;

……

int result;

fread_int32(&result,1,infile);

……

 

這樣,一個整型數據就被讀取出來存放在result中了。

 

Short

若用Java讀取短整型數據:

 

int[] byteDataInt=new int[2];

for (int i=0;i<2;i++)        

byteDataInt[i]=din.read();

for (int i=0;i<2;i++)

byteDataInt[i]=byteDataInt[i]<<8*i;    

int result=byteDataInt[0] | byteDataInt[1]; 

 

 

C語言:

fread_int16(&(result,1,infile);

 

 

Float

若用Java讀取浮點型數據:

 

int[] byteDataInt=new int[4];

for (int i=0;i<4;i++)        

byteDataInt[i]=din.read();

int symbol=byteDataInt[3] & 8;    //get the symbol

int power=(byteDataInt[3]<<1 | byteDataInt[2]>>7)-127;  //get the power

int temp= byteDataInt[2] & 127;   // let the 8th bit to be 0

int a=temp<<16 | byteDataInt[1]<<8 | byteDataInt[0];

float result=1;

for (int i=1;i<=23;i++)

{

int x=a&(int)(Math.pow(2, i-1)); //keep value of the i bite and make others bites to be 0

int xx=x>>(i-1);              // move the i bite to the right end;

double addCount=xx*(Math.pow(2,-(23-(i-1))));  // computing the increment

result=result+addCount;

}

result=result*(int)(Math.pow(2, power));

if (symbol==1)

result=-result;

 

C語言:

fread_float32(&(result,1,infile);

 

 

以上的3個例子可以看出,JavaC語言可以實現同樣的功能,但是Java卻麻煩得多,而且實驗證明,Java花的時間會多得多。如版本4的探針強度是float型的,假如一張芯片的640*640個探針強度都用Java來讀取,將會花費很長的時間,而用C語言不足1秒就可以完成。

 

 

3)版本1

版本1在版本3的基礎上又去掉了STDVNPIXELS這兩列,並且出現了fread_be_int32fread_be_uint16fread_be_float32C語言讀取方法,這些方法都有着等效的Java實現方法,但是用Java來讀取CEL文件總是很慢的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM