웹에서 구글맵을 활용한 정보 표현

구글은 여러 포털사이트 중 전 세계적으로 높은 인지도와 높은 시장 점유율을 가지고 있다. 이런 이유는 구글이 제공하는 여러 서비스(강력한 검색, 구글맵, 무료 이메일)들이 있기 때문이다. 그 중 구글에서 무료로 제공하는 구글맵 API를 이용한 웹에서 활용한 시각화법을 알아보고자 한다. 이 방법은 웹에서 구글맵을 이용하면 통계데이터나 위치기반 정보를 표현하는데 유리하다. 다시 말해 맵 위에 정보를 얹혀 사용자의 이해력을 향상시키고 직관적인 정보를 보여줄 수 있기 때문이다.

현재 구글에서 제공 중인 구글맵 자바스크립트 API 버전은 v3이다. v2도 사용은 되고 있지만 구글에서는 v3으로 마이그레이션하기를 권고하고 있다. 구글맵 API의 자세한 내용은 https://developers.google.com/maps/documentation/javascript/?hl=ko 에서 확인할 수 있다.

그럼 웹에 구글맵을 얹고 우리가 원하는 위치에 마커를 찍고 분포도에 따른 히트맵 표현 후 마지막으로 마커 개수에 따라 클러스트링 하는 방법을 알아보자.

시작은 간단하게...(웹에 맵 띄우기)
가장 먼저 심플하게 지도를 얹는 방법부터 알아보자. 아래는 전체 코드이며 앞으로 이 코드에서 소스를 추가하여 계속 응용 할 것이다.

줄 번호 보이기/숨기기
   1 <!DOCTYPE html>
   2 <html>
   3 <head>
   4 <title>google map</title>
   5 <meta charset="utf-8">
   6 <style>
   7 html,body,#map-canvas {
   8         height: 100%;
   9         margin: 0px;
  10         padding: 0px
  11 }
  12 </style>
  13 <script type="text/javascript" src="https://maps.googleapis.
com/maps/api/js?libraries=visualization&sensor=false
"></script>
14 <script> 15 var map; 16 function initialize() { 17 var mapOptions = { 18 zoom : 7, 19 center : new google.maps.LatLng(37.5651,
126.98955), //서울
20 mapTypeId : google.maps.MapTypeId.ROADMAP 21 }; 22 map = new google.maps.Map(document.getElementById
('map-canvas'), mapOptions);
23 } 24 google.maps.event.addDomListener(window, 'load', initialize); 25 </script> 26 </head> 27 <body> 28 <div id="map-canvas"></div> 29 </body> 30 </html>

맵을 띄우기 위한 가장 기본적인 라인은 13번이다. 여기서 구글에서 제공하는 API를 로드한다. 뒤에 붙는 파라미터 중 sensor는 필수사항이며, true or false를 선택할 수 있으며 의미하는 바는 사용자 위치를 확인하기 위해 센서를 사용할 것인지에 대한 명시이다. 우리는 위도, 경도 값을 이용하여 위치를 찾을 것이므로 false로 한다. 그 이외에 language=ko or en 등 언어를 설정 할 수도 있다. 설정하지 않을 시 어플리케이션의 기본언어 설정을 따른다. libraries=visualization은 마커를 사용하기 위한 라이브러리 옵션이다. 다음으로 24번 라인에 의해서 initialize함수를 호출하게 되며 이 함수에서는 초기 맵에 대해 설정을 한 후 맵을 로드하게 된다. 22번 라인에서 document에서 element id가 "map-canvas"라는 부분에 맵을 띄워라 라는 의미이다.

아래 이미지가 위 코드를 실행 하였을 때의 화면이다.



GeoCoder이용 마커표시(지역->위도경도변환)
구글에서는 지역을 입력받아 그 지역의 위도와 경도를 반환해주는 geocoder를 제공하고 있다. 아래는 해당소스이며, 반환된 위도, 경도에 마커를 찍어 보자.

줄 번호 보이기/숨기기
   1 <style>
   2         #panel {
   3                         position: absolute;
   4                         top: 5px;
   5                         left: 50%;
   6                         margin-left: -180px;
   7                         z-index: 5;
   8                         background-color: #fff;
   9                         padding: 5px;
  10                         border: 1px solid #999;
  11                 }
  12 </style>
  13 .
  14 .
  15 .
  16 var geocoder;
  17 function codeAddress() {
  18   geocoder = new google.maps.Geocoder();
  19   var address = document.getElementById('address').value;
  20   geocoder.geocode( { 'address': address}, function(results, 
status) {
21 if (status == google.maps.GeocoderStatus.OK) { 22 var lat = results[0]['geometry']['location']
['lat']();
23 var lng = results[0]['geometry']['location']
['lng']();
24 alert(address+"의 위도는 " + lat + " 이며, 경도는
" + lng + " 입니다.");
25 map.setCenter(results[0].geometry.location); 26 var marker = new google.maps.Marker({ 27 map: map, 28 position: results[0].geometry.location, 29 draggable:false, 30 animation:google.maps.Animation.DROP, 31 title:address 32 }); 33 } else { 34 alert('Geocode was not successful for the following
 reason:
' + status);
35 } 36 }); 37 } 38 . 39 . 40 . 41 <body> 42 <div id="panel"> 43 <input id="address" type="textbox" value="Seoul"> 44 <input type="button" value="GO" onclick="
codeAddress()
">
45 </div> 46 <div id="map-canvas"></div> 47 </body>

17번 라인의 codeAddress()함수에서 지역을 입력받아 위도, 경도로 변환하여 그 위치에 마커를 찍어주는 역할을 한다.



아래 소스처럼 조금 응용하면 다중마커를 찍히게 할 수 있다. 활용사례로는 지역별 감기발생현황등을 예로 들수 있다.

줄 번호 보이기/숨기기
   1 function geocode() {
   2         var addressList = new Array( '서울', '대구','광주','부산',
'포항','강릉','전주','광양','거제','김해','대전','울산','마산','수원','인천',
'
군산','파주');
3 for(var j in addressList){ 4 codeAddress(addressList[j]); 5 } 6 } 7 function codeAddress(address) { 8 geocoder = new google.maps.Geocoder(); 9 geocoder.geocode( { 'address': address}, function (results,
status
) {
10 . 11 . 12 . 13 }

실질적으로 활용을 하려면 관련 데이터가 데이터베이스화 되어 있거나 파일로 정형화가 되어 있어야 한다. 위 방법은 다중 마커를 보여주기 위해 임의로 배열을 이용하여 지역을 넣었다. 위 코드를 실행하면 아래와 같다.



다만 다중마커를 위해 geocode를 빠른시간내 지속적으로 사용하게되면 geocode was not successful for the following reason over_query_limit 라는 에러가 발생하게 된다. 이를 해결하기 위해 다음코드를 추가할 수도 있다.

줄 번호 보이기/숨기기
   1 if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {    
   2        setTimeout(function() {
   3           codeAddress(address);
   4        }, 200);
   5 }

만약 쿼리조회 중 "OVER_QUERY_LIMIT"라는 상태가 나타나면 0.2초간 대기 후 다시 쿼리를 조회하게 된다. 이렇게 되면 또 하나의 문제가 발생하게 된다. 마커를 찍는 시간이 마커의 개수에 비례하여 증가하게 된다는 것이다. 제일 좋은 방법은 지리적 정보를 데이터베이스화 하는 것이고, 추가되는 지리적 정보에 대해서만 geocode를 사용하여 결과를 DB에 추가 입력하는 방법이다.

HeatMap 표현
예를 들어 A라는 지역에 감기환자가 10명이 발생하였고, B라는 지역에 감기환자가 1명이 발생하였다고 하자. 그럴 경우 마커만으로는 정보를 보여주기에는 한계가 있다. 이를 해결하기 위해 가중치를 이용한 HeatMap을 표현할 수 있다. 방법은 아래와 같다.

줄 번호 보이기/숨기기
   1 var heatmap;
   2 var heatMapData = [];
   3         
   4 function geocode(addressList) {
   5   var addressList = new Array('서울','서울','서울','서울','서울','서울',
'
서울','서울','대구','광주','부산','포항','강릉','전주','광양','거제','김해',
'
대전','울산','마산','수원','인천','서울','대구','광주','부산','포항','강릉',
'전주','서울','서울','서울','광양','거제','김해','대전','울산','마산',
'서울','서울','수원','인천','군산','파주','서울','서울');
6 for ( var j in addressList) { 7 codeAddress(addressList[j]); 8 } 9 heatmap = new google.maps.visualization.HeatmapLayer({ 10 data : heatMapData, 11 radius : 40, 12 dissipating : true 13 }); 14 heatmap.setMap(map); 15 } 16 . 17 . 18 . 19 function codeAddress(address) { 20 geocoder = new google.maps.Geocoder(); 21 geocoder.geocode({'address' : address}, function
(results, status) {
22 if (status == google.maps.GeocoderStatus.OK) { 23 var lat = results[0]['geometry']
['location']['lat']();
24 var lng = results[0]['geometry']
['location']['lng']();
25 map.setCenter(results[0].geometry.
location);
26 var marker = new google.maps.Marker({ 27 map : map, 28 position : results[0].geomet
ry
.location,
29 draggable : false, 30 animation : google.maps.
Animation
.DROP,
31 title : address 32 }); 33 var weightedLoc = { 34 location : new google.maps.
LatLng(lat, lng),
35 weight : 2 * 가중치(숫자) 36 }; 37 heatMapData.push(weightedLoc); 38 } else { 39 alert('Geocode was not successful for
the following reason:
'+ status);
40 } 41 }); 42 }

먼저 HeatMap을 사용하기 위해 heatmap과 heatMapData를 선언을 한다. codeAddress함수내 33-36번 라인에서 가중치를 계산해주고, 계산된 가중치 값을 heatMapData에 담게된다. 5번 라인의 모든 지역에 대한 가중치가 heatMapData에 담기게 되고, 9-13번 라인에서 HeatMap 옵션을 정하고, 14번 라인에서 맵에 HeatMap을 뿌려 주게 된다.



마커 클러스터링
마커의 개수가 많아지면 시각적으로 복잡해 보이며, 화면에 마커를 뿌려 주는 시간이 마커개수에 비례하여 증가하게 된다. 이러한 문제를 해결하기 위해 구글맵은 클러스터링을 제공한다.

줄 번호 보이기/숨기기
   1 <script type="text/javascript" src="http://google-maps-utility-
library-v3.googlecode.com/svn/trunk/markerclusterer/src/
markerclusterer.js
"></script>
2 3 var markerCluster; 4 var markers = new Array(); 5 function geocode() { 6 var addressList = new Array('서울','서울','서울','서울','서울','서울','서울','서울','대구','광주','부산','포항','강릉','전주','광양','거제','김해','대전','울산','마산','수원','인천','서울','대구','광주','부산','포항','강릉','전주','서울','서울','서울','광양','거제','김해','대전','울산','마산','서울','서울','수원','인천','군산','파주','서울','서울'); 7 for(var j in addressList){ 8 codeAddress(addressList[j]); 9 } 10 heatmap = new google.maps.visualization.HeatmapLayer({ 11 data: heatMapData, 12 radius: 30, 13 dissipating: true 14 }); 15 heatmap.setMap(map); 16 17 var clusterOptions = { 18 gridSize: 30, 19 minimumClusterSize: 2 20 }; 21 markerCluster = new MarkerClusterer(map, markers,
clusterOptions);
22 } 23 . 24 . 25 . 26 function codeAddress(address) { 27 geocoder = new google.maps.Geocoder(); 28 geocoder.geocode( { 'address': address}, function
(results, status) {
29 if (status == google.maps.GeocoderStatus.OK)
 {
30 var lat = results[0]['geometry']
['location']['lat']();
31 var lng = results[0]['geometry']
['location']['lng']();
32 map.setCenter(results[0].geometry.
location);
33 var marker = new google.maps.Marker
({
34 map: map, 35 position: results[0].geometry
.location,
36 draggable:true, 37 animation:google.maps.Animat
ion
.DROP,
38 title:address 39 }); 40 markers.push(marker); 41 42 var weightedLoc = { 43 location: new google.maps.LatLng
(lat, lng),
44 weight: 2 * 가중치(숫자) 45 }; 46 heatMapData.push(weightedLoc); 47 } else if (status === google.maps.Geocoder
Status
.OVER_QUERY_LIMIT) {
48 setTimeout(function() { 49 codeAddress(address); 50 }, 200); 51 } else { 52 alert('Geocode was not successful for
the following reason:
' + status);
53 } 54 }); 55 }

마커클러스터를 사용하기 위해 1번 라인에 클러스터 관련 자바스크립트파일(js format)을 로드한다. 그리고 markerCluster와 마커개수를 담을 수 있는 markers를 선언을 한다. 40번 라인에서 마커에 정보를 markers에 담는다. 17-20번 라인에서 마커클러스터 옵션을 설정 후 21번 라인에서 맵에 뿌린다. 그러면 gridSize에 값에 따라 맵을 그리드로 나눈 후 해당 그리드 안에 있는 마커들을 클러스터링 한다.



활용방안
지역적(국내외) 통계를 다루는 데이터가 있는 곳이면 활용 가능하다. 예를 들면 당사와 같이 생물정보를 전문적으로 다루는 곳이라면 바이러스와 같은 발생 지역에 대한 분포도를 보기위해 사용할 수 있고, 교통정보를 다루는 곳이라면 시시각각 차가 막히는 구간을 Heatmap으로 표현하는 방법으로 사용될 수 있을것이다.

지금까지 웹에서 구글맵을 활용하는 방법을 간단히 알아보았다. 위와 같은 방법을 잘 활용하여 사용자가 원하는 방향의 스마트한 웹을 구현하는 것이 개발자로서 가져야 할 책임과 임무라고 생각하며 이 글을 마친다.


작성자 : 데이터사이언스센터 통합개발실
최석문 주임 개발자

Posted by 人Co

2015/03/23 10:45 2015/03/23 10:45
Response
No Trackback , No Comment
RSS :
https://post-blog.insilicogen.com/blog/rss/response/175



일정

일시 : 20154월 1(수)~ 4월 3(금)

장소 : KT인재개발원 1연수관 204호


목표

R 초보자들의 실제 유전체 자료 분석을 수행할 수 있는 역량 개발


내용

R을 활용한 NGS 데이터 분석

(자세한 프로그램 내용은 http://kobicedu.labkm.net 참고)



신청방법

신청기간 : 20153월 19(목) ~ 2015년 3월 22(일)

선발인원 : 30

우선 선발 사항 :

  1) 유전체 자료 분석 경험자

  2) R 사용 경험자

  3) 학생 및 연구원

선발안내 : 2015년 3월 23일(월) ~ 2015년 3월 24일(화)

교육비 : 무료 (중식 무료제공)

준비물 : 유무선 인터넷이 가능한 개인 노트북

신청방법

  - 온라인 신청 http://kobicedu.labkm.net

문의

  - ㈜인실리코젠 (031-278-0061, edu@insilicogen.com)

  - 문의게시판 이용 http://kobicedu.labkm.net/labboard/board/QnA


Posted by 人Co

2015/03/17 14:46 2015/03/17 14:46
Response
No Trackback , No Comment
RSS :
https://post-blog.insilicogen.com/blog/rss/response/174

분자진단 시장의 발전

“시퀀싱은 클리닉으로 이동 중”

분자진단 시장은 임상의학에서 유력한 플랫폼이 되고 있으며 진단 시장 중 급성장하고 있는 부문 중 하나이다. "글로벌 기업인 GE가 막강한 자본력을 바탕으로 M&A, 브랜드 파워를 앞세워 암 분자 진단 시장에 진출하다.“, "급성장하는 질병 분자진단 산업…로슈가 장악했던 세계 시장에 씨젠·랩지노믹스 등 도전장" 등 최근의 뉴스를 통해서도 그 내용을 확인할 수 있다. 이는 맞춤형 의료 수요가 증가 하고 있다는 것을 반증하며 분자 진단 시장이 뜨고 있음을 알리고 있다. 현재 분자진단 시장은 선진국의 일부 업체들이 독점시장을 형성하고 있는데 최근 국내 바이오기업들도 새로운 기술을 바탕으로 진단 시장에 뛰어 들고 있다. 바이오니아, 진매트릭스, 씨젠 등은 분자진단 시장에서 성과를 내기 시작했으며 해외 진출도 진행하고 있다. 개인에 있어 신약의 치료 효과를 높이고 부작용을 최소화하는 맞춤형 의료에 대한 수요 증가로 분자 진단 시장이 급속히 발전하고 있다.
< 분자 진단 출처:http://advameddx.org >


“환자의 몸에 특정 유전자의 존재 유무를 통해
질병 또는 병원균의 감염여부를 판단 ”

진단을 맞춤형의학에 적용하기 위해서는 민감도가 높아야 하고 진단을 하는데 걸리는 시간도 짧고 비용이 낮아야 하는데 분자 진단은 이를 만족시킬 수 있는 방법이다. 분자 진단은 DNA, RNA, Protein을 기반으로 유전자와 대사 기능, 의약품의 대사 반응, 질병 관계를 평가하는 검사로 면역 조직 진단검사, 유전자 진단 검사 등을 포함한 광대한 영역이다. 분자 진단은 글로벌 제약사를 중심으로 정확한 설계와 선별을 통해 연구 생산성을 높이고 임상에서의 성공률, 시간 단축, 비용 절감을 위해 연개 개발에 집중 투자하고 있다. 특히 바이오의약 업계의 핵심 과제인 백신치료제, 유전자 치료 등 효과적인 개발을 위하여 바이오마커를 활용하는 것이 필수적이며 마커의 특징을 통해 개인맞춤형 치료제 개발이 향후 의약 업계의 패러다임이 될 것으로 예측된다. 향후 개인별 분자 표적 항암제가 항암제 치료의 핵심 기술이 될 것으로 추정되는 만큼 각종 분자 표적 항암제의 투여 여부 및 대사 반응성, 적정 용량의 결정을 위해 분자 진담 검사의 이용이 급속히 증가될 전망이다.

* IVD : In Vitro Diagnostics

분자진단 장비 및 분석시장은 세계적으로 30억 달러의 시장을 형성하고 있으며 년평균 성장률은 13%로, 유전자 분석기, 단백질 분석기, 메타볼로믹 및 휴대형 진단기 등 장비 및 도구산업을 중심으로 발전하고 있다. 한편 세계 분자진단 시장은 2004-2010년까지 연평균 10.9% 성장하여 2010년 31억 달러 규모이지만 2010-2016년까지 연평균 9.5% 성장하여 2016년 53억 달러 규모로 성장할 것으로 예상된다.


< 분자 진단의 영역별 시장 규모 >


분자 진단은 지금까지 숙련된 전문가와 고가의 시험장비가 필요했으나, 비용 절감, 자동화, 첨단 기술 도입에 의해 분자 진단 검사의 사용이 확대되고 있다. 원내감염 발병률 상승, 고령화, 환자 의식 향상 등 다양한 요인에 의해 시장은 향후에도 계속 성장할 것으로 예측된다. 또한 임상의학에서 유력한 플랫폼이 되고 있으며 진단 시장 중 급성장하고 있는 부문 중 하나이다. 수많은 분자검사가 CE 마크와 FDA 승인을 획득하고 있는것이 이를 반증하고 있다.

분자진단기술(PCR, Next Generation Sequencing, Microarray, Infectious diseases, Genetic disease, Oncology testing, Blood donor screening)은 급속히 진화하고 있는 분야로 새로운 기술과 응용이 차례로 등장하고 있다. 분자 진단에 포함되어 있는 기술에는 1세대 PCR 증폭, DNA Probe, 형광 In-situ Hybridization, 2세대 바이오칩과 마이크로 유체, 차세대 신호 검출, 바이오센서, 분자마커, 유전자 칩을 이용한 유전자 발현 프로파일링 등이 있다. 이들 기술은 암의 치료 분자를 발견하고, 환자의 스크리닝과 진단, 분류, 투약 치료의 최적화에 크게 기여하고 있다.



< 분자 진단 기술 출처: http://en.wikipedia.org/ >


최근 수년간 분자 진단 분야에서는 몇가지 획기적인 개발이 진행되고 있다. 그 중에서도 염기서열분석은 염기서열 이상으로 발생된 유전질환을 진단하기 위한 표준 검사로 분자 진단 검사에서는 핵심 진단기술로 발전했다. 1977년 Sanger에 의해 개발된 이후 약 25년간 널리 사용되다 최근에 더욱 빠른 속도로 발전하여 전혀 새로운 개념의 기술인 차세대 염기서열 시퀀싱(NGS)이 등장하였다.


< NGS 서열 분석 출처: http://bioinf.comav.upv.es >

유전체는 유전자의 전체를 의미한다. 유전체 기반의 분자 진단이라 하면 유전자 전체를 읽어 분자 진단에 활용하는 기술이다. 유전체 시퀀싱 비용이 감소하면서, 유전자 한 두 개를 읽어서 분자 진단을 하던 방법에서 벗어나 전체 유전체를 읽어 분자 진단을 해도 비용 대비 상당 효과를 볼 수 있는 시대가 되었다. 단 한 번의 분자진단을 통해 기존의 다양한 분자 진단들을 한꺼번에 처리할 수 있어 매우 효율적이다.

개인 유전체 분석을 통한 중증 난치성 질환 및 퇴행성 질환의 조기 발견은 생명 연장 및 삶의 질 향상과 직결된다. 유전자 변이, 유전자 SNP(Single Nucleotide Polymorphism), 유전자 CNV(Copy Number Variation)가 질병에 미치는 상관 관계가 불명확함에도 불구하고 특정 질환 발병 가능성을 예측하여 발병 위험도를 알리는 스크리닝 지표로 사용되고 있다.

Human Genome Project가 끝나고 난 이후, 유전체 연구를 통해 얻어진 지식을 기반으로 유전자를 기반으로 하는 분자 진단 방법들이 속속 개발되었고, 이들 중 몇몇은 상업화 되어 크게 성공하기도 하였다. 분자 진단은 빠르고 값싼 유전체 시퀀싱 기술로 가장 먼저 효과적으로 산업적인 진보를 이뤄낼 수 있는 분야이고, 자연스레 분자 진단에 접목된 제품들이 하나 둘 시장에 출시되고 있다.


< Myriad genetics사의 BRACAnalysis 출처: https://www.myriad.com >

대표적인 성공 사례는 유방암과 관련된 상품으로 Myriad genetics사의 RACAnalysis(매출액: 7,000억)와 Genomic Health사가 출시한 OncotypeDX(매출액: 2,000억)가 있다. Myriad Genetics의 BRAC Analysis는 BRCA1 및 BRCA2 유전자 변이를 분석하는 유전자 진단 제품이다. 질병 예측을 위한 유전자 검사는 미국에서 DCT(Direct to Consumer Genetic Test)로 상업화되어 있다. 23andMe, deCODE Genetics, Navigenics 등은 유전체 분석을 통해 당뇨, 심근경색, 전립선암 등 20-90개 질환에 대한 유전적 형질을 분석하여 질병 예측 진단 서비스를 제공하고 있다.


< DCT 서비스 : 23andMe >

유전자 진단을 통한 질병 진단 검사는 개인 및 환자별 특정 유전자 유무에 따라 특정 질환에 대한 발병 가능성을 예측함으로써 질병 조기 진단, 생활 습관 조정 및 예방 요법을 통해 질병 발병 시기를 늦추어 줄 것으로 기대된다. 또한 상당수의 약물 부작용 사례에서 보듯이 동일한 질환을 가진 환자가 동일한 의약품에 대해 서로 상이한 반응을 보이듯 환자별 유전적 차이로 인해 특정 유전자 변이가 특정 치료제의 안전성, 유효성, 약물 용량에 미치는 영향 평가 등을 위한 주요 도구로써 활용될 수 있다. 유전자 진단을 통한 약물사전 검사는 환자별 특정 유전자 유무에 따라 특정 치료제의 안전성, 유효성, 약물 용량을 결정함으로써 약물 요법 최적화 및 약화 사고를 줄 일 수 있을 것이다.

유전체 해독 기술 발달로 유전체 해독 데이터 생산량은 천문학적으로 증가하고 있으나 방대한 정보를 저장하고 분석하여 의미있는 결과를 이끌어 내기는 상당히 어렵기 때문에 바이오 빅 데이터(Bio-Big Data)를 저장, 분석하여 유의미한 정보를 도출하는 바이오정보학의 발전이 시급하다.

진단 목적의 검사로 지금 당장 상용화하기에 기술적, 분석적 어려움이 존재하지만 NGS 기술은 조만간 분자진단시장에서 가장 중요한 검사 기술이 될 것이다.

작성자 : DX팀 조관희 팀장

Posted by 人Co

2015/03/03 13:48 2015/03/03 13:48
Response
No Trackback , No Comment
RSS :
https://post-blog.insilicogen.com/blog/rss/response/173