bfconvert에서는 Object 위치를 좌표로 보내는 기능이 있다. 문제라면 소수점이 있는 실수라는 것이다. 그러나 픽셀에서는 소수점 값이 없으므로 정수로 변환이 필요하다. bc는 기본적으로 내림으로 결과를 처리한다고 하므로 이를 이용한다. 1로 나눈 값을 버림으로 처리하면 정수로 된다.
echo "$Location_Center_X/1" | bc
bfconvert에서는 Object 위치를 좌표로 보내는 기능이 있다. 문제라면 소수점이 있는 실수라는 것이다. 그러나 픽셀에서는 소수점 값이 없으므로 정수로 변환이 필요하다. bc는 기본적으로 내림으로 결과를 처리한다고 하므로 이를 이용한다. 1로 나눈 값을 버림으로 처리하면 정수로 된다.
echo "$Location_Center_X/1" | bc
Shell에서는 기본적으로 정수만 사칙 연산이 된다. 그래서 8.0이 0보다 크냐고 조건문을 만들면 integer 값이 필요하다며 거부한다. 매우 빡치는 일이지만 해결 방법은 있다. 내가 이용한 방법은 bc를 이요한 것이다.
echo "사칙연산" | bc
이렇게 하면 연산이 가능하다.
12.0 > 0의 참/거짓을 판단을 하면 된다. 참일 경우는 1, 거짓일 경우는 0을 출력한다. 이를 이용한다.
if [ $(echo "${NUM1} > 0" | bc) -eq 1 ]; then
명령어
fi
R의 matrix나 data.frame 구조로 받아오는 방법을 몰라서 일단 한 줄씩 값을 읽어서 판별하는 방법을 기반으로 하였다.
INPUT1=/home/byun1114/work/MyExpt_Image.csv
while IFS=, read [컬럼 이름 모두를 빈 칸으로 구별]
do
if [ "${첫 번째 컬럼}" != "첫 번째 컬럼" ]; then
{명령어}
fi
done < $INPUT1
여러 방법이 있는 듯 한데, 결국 쉽게 할 수 있는 것은 IFS에서 구분 기호를 ,로 입력해서 불러오는 것이었다. SQL에서와 비슷하게 read 이후에 모든 컬럼 이름을 써야 헷갈리지 않는다.
if 구절이 있는 이유는 header 값이 있는 경우를 구별할 수 없기 때문이다. 제목의 첫 줄에 명령어를 바로 적용하지 않도록 해야 한다.
제목은 거창한데 실제 구현하고자 하는 것은 동시에 여러 프로세스를 실행하는 것이다. 여러 CPU를 동시에 사용하는 프로그램으로 제작된 것이 아닌 이상 다중 코어 기반의 현재 CPU에서는 idle CPU를 줄이는 것이 시간을 아끼는 일이고, 퇴근 시간과 연구 시간을 줄이는 것이다. bfconvert를 이용하고 있는 지금의 나에게는 파일 변환 시간을 줄이는 것이다. SVS 파일을 4000×4000 pixel로 분할하는 작업을 실행하면 CPU는 100% 정도 밖에 되지 않는다. 나머지 코어 5개 분량은 놀고 있는 것이다. SVS 파일을 통째로 TIFF로 변환하면 250% 정도로 상승하지만 여전히 노는 CPU 자원이 생긴다. 그래서 원하는 수준으로 적당히 여러개를 실행할 수 있는 것이 필요하다.
실행에 시간이 짧게 걸리거나 시스템에 부하가 많이 없다면 한 번에 다 실행하는 방법도 좋을지 모르겠다. 이 방법은 반복문에서 실행 부분에 &를 붙여 모두 백그라운드에서 실행하게 하면 된다.
먼저 알아두어야 할 것은 bfconvert는 실행하면 1초쯤 후에 java 프로세스로 실행이 된다.
나의 목표는 동시에 2 ~3개 정도에서 조절해 보는 것이다. 여러 방법 중에서 조건문 if와 wait를 이용해 보기로 했다. 여유있게 하나 실행하고 10초후에 다시 판정하는 방법을 이용했다. 기다리지 않으면 앞서 언급한 시간차(?)로 인해서 목표한 2개가 아닌 3개가 실행되는 사태가 생긴다. 처음에 if 의 조건문이 자꾸 오류가 나서 찾아본 결과, 대괄호에 띄어쓰기가 필요하다는 것을 알았다.
이 방법은 좋은데 백그라운드로 2개가 동시에 실행되고 있는 경우, 2개가 모두 종료되어야 3번째가 실행이 된다. 그리고 bfconvert는 2번째 변환되는 파일은 속도가 좀 느려진다. 1번째 파일의 변환이 끝나면, 2번째 파일이 혼자 변환되는 것이다.
for file in $file_list; do
child_proc=`ps -e | grep java | wc -l`
if [ "${child_proc}" -eq 2 ]; then
wait
fi
file=`basename $file .svs`
~/bftools/bfconvert -series 0 -bigtiff ${file}.svs converted/${file}.tif &
sleep 10
done
계속 2개를 유지시키기 위하여 if 를 기반으로 한 조건문을 여러 번 변경해 보았는데 잘 되지 않았다. 그래서 방법을 좀 바꾸어서 무한 반복 while을 이용해 보기로 했다. 하나씩 계속 실행하다가 실행중인 java 프로세스가 2개 이상이면 일단 60초 대기 후 다시 java 프로세스 숫자 확인한다. 하나가 종료되었다면 while 구문에서 벗어나서 새롭게 변환 프로세스를 실행하는 방식이다. 쉘 스크립트의 숫자 판별식이 등호나 부등호를 이용하지 않기 때문에 매우 적응이 안되는데, 본인의 시스템에 맞는 적절한 숫자와 조건을 이용하면 될 것이다.
for file in $file_list; do
file=`basename $file .svs`
~/bftools/bfconvert -series 0 -bigtiff ${file}.svs converted/${file}.tif &
sleep 10
while :
do
child_proc=`ps -e | grep java | wc -l`
if [ "${child_proc}" -lt 2 ]; then
break
fi
sleep 60
done
done