IMAGE 함수 질문드립니다.

게시판 IDL Q&A IMAGE 함수 질문드립니다.

이 게시글은 4개 답변과 3명 참여가 있으며 마지막으로  HPkim에 의해 6 일, 4 시간 전에 업데이트 됐습니다.

  • 글쓴이
  • #5412

    HPkim
    회원

    안녕하세요,

    2차원 스펙트럼을 그리려고 합니다.
    Y축은 주파수, X축은 시간 (JULIAN DAY)인데,
    계속 qhull precision error가 발생합니다.
    시간 간격이 일정하지 않은 경우 에러가 발생하게 되나요?
    어쩔때는 “triangle is not in countclockwise order” 라는 에러도 발생합니다.

    SAVE 데이터
    https://drive.google.com/open?id=1VbImljgmao1IELIZHQhWWHxqhlaY0jSS

    코드
    PRO TEST

    RESTORE, ‘D:\data’
    HELP, spectrum, time, frequency
    win=WINDOW(DIM=[1000,500])
    dum=LABEL_DATE(date_format=’%H:%I’)
    c=COLORTABLE(33)
    c1=IMAGE(spectrum, time, frequency, YTITLE=’Frequency [Hz]’, RGB_TABLE=c,AXIS_STYLE=2, ASPECT_RATIO=10, YLOG=1, /CURRENT)

    END

  • #5413

    Sangwoo
    회원

    올려주신 데이터를 갖고 유사한 표출을 시도해보았는데, 말씀하신 것과 같은 문제가 발생하는 것을 확인하였습니다. 이 문제는 설명을 하자면 약간 복잡한데요. 원본 데이터에서 spectrum이란 배열은 2200×82의 구조를 갖는 2차원 배열이고, time과 frequency는 각각 2200개 및 82개 짜리 1차원 배열입니다. 그런데 time의 값들은 간격이 일정하지 않고, frequency의 경우는 어느 정도 일정한 것 같으나 소수점 단위까지 따졌을 때 완벽하게 간격이 일정하지는 않을 수도 있습니다. 따라서 이렇게 X 또는 Y 방향 중 어느 한 방향으로라도 격자 간격이 일정하지 않을 경우에는, IMAGE 함수에 인수를 spectrum 하나만 주는 대신 spectrum, time, frequency 등 세 개를 줄 수 있습니다.

    그런데 이렇게 격자 간격이 일정하지 않을 경우에는 IMAGE 함수가 자체적으로 내삽기법을 사용하여 등간격 그리드로 재설정을 일단 먼저 한 다음에 표출을 하게 되어 있습니다. 즉 원본 데이터가 2200×82라 하더라도 이걸 내삽 처리하여 예를 들면 400×400과 같은 형태로 바꾼 다음에 표출을 하게 됩니다. 이 내용은 IMAGE 함수에 관한 도움말 내용에서 Automatic Gridding이라는 작은 섹션에서 간단하게 소개되어 있긴 합니다. 이와 관련해서는 더 설명할 수도 있지만 너무 길어지므로 일단 여기까지만 언급합니다.

    그런데 이렇게 격자 재설정을 하는 과정에 있어서 원본 데이터의 X방향 및 Y방향의 좌표값 크기나 범위 등이 너무 차이가 나는 경우에는 재설정을 위한 내삽 처리가 제대로 안될 수도 있습니다. 이미 보셨던 Qhull precision error도 이러한 증상이라고 보시면 됩니다. 이런 일이 발생하는 이유는 X축 방향의 좌표값 범위가 2456421.1부터 2456421.3까지인 반면, Y축 방향의 좌표값 범위는 4.0부터 5.69까지로 양쪽이 서로 너무 차이가 나기 때문인 것으로 보입니다. 그래서 이러한 데이터 특성을 감안한 표출 과정이 따로 필요한 것으로 보이는데, 어떤 방식으로 갈 것인가에 대한 선택지들은 몇가지가 있습니다. 가장 간단한 방법이라면 X축 범위와 Y축 범위 사이의 괴리감(?)을 어느 정도 줄여나가는 것인데요. 예를 들면 다음과 같이 X축 범위를 원본상의 Julian Day 단위로 두지 않고, 특정 기준 시간 이후의 시간(hour)수로 환산하는 것입니다.

    tj0 = JULDAY(5, 8, 2013, 14, 0, 6)
    time_new = 24L*(time-tj0)

    데이터를 보니까 시작 시각이 2013년 5월 8일 14시 00분 06초라서 기준시각을 이렇게 가정한 후, time 배열 내 모든 값들에 대하여 이 기준시각을 빼준 다음, 거기 24을 곱하여 시간 단위의 값이 되도록 환산한 것입니다. 이런 과정을 거친 후 다음과 같이 IMAGE 함수를 사용해보았습니다.

    im = IMAGE(spectrum, time_new, frequency, YTITLE=’Frequency [Hz]’, RGB_TABLE=c, $
    AXIS_STYLE=2, ASPECT_RATIO=0, YLOG=0, YRANGE=[4, 5.7], MARGIN=0.1, /CURRENT)

    여기서는 편의상 Y축에 대한 로그 스케일 처리는 하지 않았습니다. 로그 스케일의 축 처리는 또 다른 토픽이라서 이것도 또 다른 스토리입니다. 이와 같이 해보시면 어느 정도 그림은 나옵니다. 다만 이 방법의 문제점은 X축을 환산했기 때문에 원래의 Julian Day 스케일로 처리하기가 좀 난감하다는 점 그리고 이미지의 격자구조가 재설정된 상태라서 해상도가 다소 아쉬울 수 있다는 점 등이 있습니다. 물론 이러한 단점을 극복하기 위한 별도의 방법들도 따로 있겠으나, 여기서 댓글의 형태로 더 언급하기는 매우 힘듭니다. 그래서 일단은 이 정도로만 언급해두겠습니다.

    • 이 답변은  Sangwoo에 의해 2 주, 2 일 전에 수정됐습니다.
    • 이 답변은  Sangwoo에 의해 2 주, 2 일 전에 수정됐습니다.
  • #5416

    tlseorb0111
    회원

    안녕하세요

    또 다른 방법 한가지를 더 소개해 보겠습니다.

    아래 첨부한 코드 중 rebin_img를 사용하는 것인데요,
    rebin_img 코드는 사용자가 넣어준 데이터를 균일한 간격으로 선형 내삽해주는 코드입니다.
    data는 첨부해주신 데이터의 spectrum에 해당되는 것이고, x, y 각각 time과 frequency에 해당됩니다.
    xdim, ydim 은 rebin_img 에의해 선형 내삽된 이미지의 새로운 dimension이며, 이 값들은 적당한 값을 임의로 주시면 될 듯 합니다.
    사용법은 test6 코드에 간단히 적혀 있구요.
    간단한 코드이기에 따로 설명하지 않아도 코드를 보시면 내용을 금방 파악하실 수 있을 것입니다.

    function rebin_img, data, x, y, xdim=xdim, ydim=ydim

    !null = histogram([min(x), max(x)], nbins=xdim, loc=xloc)
    !null = histogram([min(y), max(y)], nbins=ydim, loc=yloc)

    xidx = interpol(dindgen(n_elements(x)), x, xloc)
    yidx = interpol(dindgen(n_elements(y)), y, yloc)

    intp_data = interpolate(double(data), xidx, yidx, /grid, missing=!values.f_nan)

    return, {data:intp_data, xaxis:xloc, yaxis:yloc}

    end

    pro test6

    restore, ‘data’

    out = rebin_img(spectrum, time, frequency, xdim=400, ydim=400)

    dum=label_date(date_format=’%h:%I’)

    i = image(out.data, out.xaxis, out.yaxis, $
    axis=1, $
    aspect_ratio = 0, $
    pos = [0.1, 0.1, 0.9, 0.9], $
    ytitle = ‘Freq’, $
    xtitle = ‘Jul’, $
    xtickformat=’label_date’, $
    rgb_table = 33)

    end

  • #5417

    Sangwoo
    회원

    예 위와 같은 방법으로 처리해도 충분할 것 같습니다. 원본 데이터의 격자수에 최대한 가까운 모습으로 처리하려면 위의 코드에서 rebin_img가 사용된 부분을 다음과 같이 해도 됩니다.

    out = rebin_img(spectrum, time, frequency, xdim=2200, ydim=82)

    사실 원본 데이터의 격자 간격이 불규칙이긴 하지만, 불규칙의 정도가 크지 않아서 거의 규칙 격자에 가까운 형태라고 볼 수 있습니다. 따라서 위와 같이 처리하면 원본 데이터와의 괴리감이 거의 들지 않는 선에서 표출 처리가 가능하리라 생각됩니다.

  • #5419

    HPkim
    회원

    덕분에 좋은 정보 알게되었습니다. 감사드립니다 !!!

답변은 로그인 후 가능합니다.