[카테고리:] Data Science for MSE

  • TMA 분석데이터 처리 자동화 (1)

    TMA (Thermomechanical Analysis)는 온도 변화에 따른 시료의 길이 변화를 측정하는 장치입니다. 따라서 기울기값이 그대로 해당 온도 구간에서의 열팽창계수가 되며, 열팽창계수의 변곡점을 통해 비정질 소재의 유리전이온도 (Tg)를 예측할 수 있습니다. TMA에 대한 정보는 별도의 포스팅을 통해 다루도록 하고, 여기서는 제가 결과 데이터를 처리하는 방식에 대해 한번 얘기해 보겠습니다.

    측정을 마치고, 결과 테이블을 export한 뒤 메모장 등에서 불러보면 아래와 같은 형식으로 저장이 되어 있습니다.

    CUE
    Title                                                           01.12.2022 13:03
    ________________________________________________________________________________
    
    Title
    Evaluation Categories:
    
    Curve Name:
      221201_#968_noGV-3, 01.12.2022 12:35:27
      Performed 01.12.2022 12:35:27
    Curve Values:
              Index              t             Ts             Tr          Value
                               [s]           [�C]           [�C]           [�m]
                  0              0         27.940         30.000        3722.26
                 18             18         31.083         33.000        3722.26
                 36             36         34.055         36.000        3722.27
                 54             54         37.031         39.000        3722.32
                 .
                 .
                 .
               1656           1656        305.188        306.000        3737.23
               1674           1674        308.191        309.000        3735.29
               1692           1692        311.209        312.000         3731.4
               1710           1710        314.241        315.000        3725.92
    
    
    Results:
      Exp. Coeff.	8.70 ppm * K^-1
      Left Limit	98.68 �C
      Right Limit	200.19 �C 
      Result Mode Sample Temp
      Heating Rate	10.00 �Cmin^-1
    
      Glass Transition
      Onset	287.67 �C
      Left Limit	272.24 �C
      Right Limit	292.78 �C
      Heating Rate	10.00 �Cmin^-1
      Result Mode  Sample Temp
    
      Extrapol. Peak	303.61 �C
      Peak Value	3737.39 �m
        normalized	100.41 %
      Left Limit	299.52 �C
      Right Limit	306.20 �C
      Heating Rate	10.00 �Cmin^-1
      Result Mode    Sample Temp
    
    Texts:
    
      221201_#968_noGV-3, 01.12.2022 12:35:27
      221201_#968_noGV-3, 3.7223 mm
    
    Sample:
      221201_#968_noGV-3, 3.7223 mm
    Sample Remarks:
      
    Experiment Comments:
      -
    Curve Categories:
    Evaluation:
      
    Method:
      A220921_315N2_V
    Adjustment:
      From 0.00 to 28.50 min
      Sample Temperature:
        KTypSDTA, adjusted 05.04.2019 13:12:47
        Tc     : 25.00 �C
        dTs(T)   : 0.2934 + 269.1799e-06*T + 0.0000*T^2 �C
        Tau Lag: 10.5860 + 6.0064e-03*T - 6.0820e-06*T^2 s
    
    
      Force Offset: 54080 Bit
            Slope : -43070.000 Bit/N
          adjusted: 24.12.2021 12:39:05
      Length      : 0.602 | 0.000 | 0.000 nm/Bit
          adjusted: 24.12.2021 12:45:27
    KTyp, adjusted 05.04.2019 13:12:05
    Tc     : 25.00 �C
    dTc(T)   : 3.7363 - 3.5045e-03*T + 0.0000*T^2 �C
    
    Sample Holder:
      Probe Flat, 3.0 mm, Quartz
    Order Number:
      
    Customer:
      
    User:
      Luke
    
    
    ________________________________________________________________________________
    Not signed                                                        STARe SW 15.00

    TMA를 루틴하게 측정하는 사람이라면, 동일한 조건 (온도 구간, 승온속도, 분위기 등)에서 여러개의 샘플을 분석하는 경우가 가장 흔하겠죠. 그렇다면 데이터 테이블 위아래의 부가 정보들은 매번 확인할 필요가 없습니다.

    저는 샘플 온도 (Ts)와 길이값 (Value) 이렇게 두개만 쓸거기 때문에, 나머지는 전부 잘라주도록 하겠습니다.

    Python
    f = open("파일명", "r")
    df_idx = pd.DataFrame(f)
    idx = df_idx[df_idx[0].str.contains("Curve Value")].index
    f.close()

    idx를 출력해보면 아래와 같은 결과를 확인할 수 있습니다.

    Index([9], dtype=’int64′)

    “Curve Values”라는 텍스트가 위에서 10번째 줄 (파이썬은 0부터 세니까요)에 있네요. 그 아래부터 데이터 테이블이니까, skiprows 매개변수로 해당 줄까지 지워버리도록 합니다. 이 때 유의해야 할 점은 데이터 아래쪽으로도 세팅이나 설비 관련 정보가 들어있다는 겁니다. 이 부분은 구분된 항목의 갯수가 데이터 열과 상이하기 때문에 오류 발생을 방지하기 위해 on_bad_lines = “skip” 매개변수를 추가해 주겠습니다.

    Python
    f = open("파일명", "r")
    # csv가 아닌 다수의 공백으로 구분된 데이터이므로 read_table 매개변수와 구분자 "\s+" 사용
    # skiprows를 숫자 10이 아닌 idx로 변경 (저장하기에 따라 달라질 수 있으므로)
    df = pd.read_table(f, on_bad_lines = "skip", sep = "\s+", skiprows = int(idx[0]) + 1)
    f.close()
    
    df

    df를 출력하면 아래와 같이 나옵니다.

    	Index	t	Ts	Tr	Value
    0	[s]	[°C]	[°C]	[µm]	NaN
    1	0	0	28.965	30.000	4665.83
    2	18	18	32.005	33.000	4665.92
    3	36	36	35.030	36.000	4666.02
    4	54	54	38.099	39.000	4666.13
    ...	...	...	...	...	...
    144	Customer:	NaN	NaN	NaN	NaN
    145	User:	NaN	NaN	NaN	NaN
    146	METTLER	NaN	NaN	NaN	NaN
    147	______________________________________________...	NaN	NaN	NaN	NaN
    148	Not	signed	STARe	SW	15.00

    이번에는 데이터 테이블 아래쪽의 텍스트들을 지워 보겠습니다. 먼저 데이터 테이블 바로 아래에 있는 “Results:”라는 문구와 마지막 줄에 있는 “STARe”가 몇번째 줄인지 인덱스를 구해 보겠습니다.

    Python
    import numpy as np
    
    # 제거할 행의 범위 (시작행, 마지막행) 인덱스 도출
    textrows_start = np.int64(df.index[(df["Index"] == "Results:")]).item()
    textrows_end = np.int64(df.index[(df["Ts"] == "STARe")]).item()
    
    print(textrows_start, "|", textrows_end)

    결과는 100 | 148 이네요. 이제 df.drop 함수로 100번째 줄에서 148번째 줄까지를 삭제하면 됩니다.

    Python
    tma_df1_x = df.drop([i for i in range(textrows_start, textrows_end + 1)], axis = 0)
    
    # 문자열이 성공적으로 제거되었는지 확인
    tma_df1_x
    	Index	t	Ts	Tr	Value
    0	[s]	[°C]	[°C]	[µm]	NaN
    1	0	0	28.965	30.000	4665.83
    2	18	18	32.005	33.000	4665.92
    3	36	36	35.030	36.000	4666.02
    4	54	54	38.099	39.000	4666.13
    ...	...	...	...	...	...
    95	1692	1692	312.275	312.000	4676.34
    96	1710	1710	315.198	315.000	4676.82
    97	1728	1728	318.129	318.000	4676.8
    98	1746	1746	321.090	321.000	4675.2
    99	1764	1764	324.098	324.000	4670.7
    100 rows × 5 columns

    불필요한 텍스트가 제거되고 깔끔하게 데이터 테이블만 남았습니다. 이제 이대로 엑셀에서 열 수 있도록 csv로 export해도 되고, 파이썬에서 직접 plot하거나 원하는 연산을 수행할 수 있습니다.