TDR: locate a boundary from polarity and round-trip delay
한국어 원문으로 표시합니다.
목표
반사의 부호와 왕복 지연으로 한 임피던스 경계를 복원하고, 반사 없는 경우는 위치 관측 불가로 남깁니다.
예상 80분입니다. 기본 세션 60분이 끝나기 전에 +시간으로 연장하세요(최대 180분). 파드 파일은 종료하면 사라집니다. 소스와 결과를 종료 전에 별도로 보관하세요. 선수 지식은 앞 신호 무결성 실습, Python 함수·리스트·JSON·파일 처리입니다.
왜 중요한가
값이 맞아 보여도 반사 부호·시간 원점·왕복 구간을 섞으면 다른 경계를 보고하게 됩니다. 설정에 적은 위치를 그대로 결과에 쓰는 오류와 반사 없는 파형에서 위치를 만들어내는 오류를 함께 막습니다. 회로는 이상적 단일 모드 무손실 선로이며 실물 계측·인증을 대신하지 않습니다.
단계
- analyze.py의 config(value)를 작성합니다. 객체 키는 lead_ns·tail_ohm·rise_ns만 허용합니다. 값은 각각 2/3/4, 25/50/100, 0.2/0.6 중 하나입니다. bool·문자열·NaN·무한대·누락·추가 키를 ValueError로 거절하고 원본을 바꾸지 않은 새 dict를 반환하세요. import만으로 실행하거나 출력하지 마세요.
- read_trace(path)는 2MiB 이하의 time v(tx) 헤더를 가진 공백 구분 TSV를 읽어 [(time_ns,voltage_v),...]를 반환합니다. 두 열 모두 유한 수치, 시간은 0 이상 엄격 증가여야 합니다. 최소 100행, 첫 시각 0, 마지막 시각 16ns(오차 1e-9ns 이하)가 필요합니다. 손상·부족 데이터는 ValueError이며 파일을 수정하지 않습니다. 최초 파일의 time 단위는 s입니다.
- plateaus(rows)는 ns/V 두 열의 목록을 받아 닫힌 창 [2,3]ns의 중앙값 launch_v와 [12,14]ns의 중앙값 settled_v를 반환합니다. 각 창에는 최소 두 점이 필요합니다. 행은 둘 이상, 시각은 0 이상 엄격 증가, 값은 불리언이 아닌 유한 숫자여야 하며 부족·손상은 ValueError입니다. 원본 행은 변경하지 마세요.
- reflection(launch_v,settled_v)는 gamma=(B-A)/A와 z_ohm=50*(1+gamma)/(1-gamma)를 반환합니다. 입력은 유한 숫자이며 bool 금지입니다. A>0, -1
- crossing(rows,threshold_v,after_ns,direction)는 direction=정수 1 또는 -1의 첫 교차 시각 ns를 반환합니다. 상승은 a.vthreshold>=b.v인 구간을 선형 보간하고, 결과 시각>=after_ns인 첫 사건을 선택합니다. 없으면 None입니다. rows는 3단계와 같은 유효성 조건, after_ns는 유한 0 이상, 임계값은 유한 수치입니다. 잘못된 값·bool 방향은 ValueError입니다.
- analyze(folder)는 config.json과 trace.tsv를 읽고 config, launch_v, settled_v, gamma, z_ohm, launch_ns, return_ns, distance_m, echo, consistent, simulated, physical_certified를 반환합니다. 출발은 A/2 상승 교차, 반사가 있으면 귀환은 after=3ns의 (A+B)/2 교차(부호 방향)입니다. echo는 |gamma|>1e-6이며 아니면 귀환·거리 모두 None입니다. 거리는 0.2*(귀환-출발)/2m입니다. 시각이 없으면 거리도 None입니다. simulated=True, physical_certified=False를 지킵니다. 일치 기준은 아래 참고를 따릅니다.
- campaign(values,folder)는 서로 중복되지 않는 1~12개 설정의 list 전체를 사전 검증한 뒤 새 폴더를 만듭니다. 각 설정으로 제공된 simulator.capture(config,folder/case-NN)를 실행하고 analyze로 분석합니다. NN은 입력 순서의 두 자리 00부터입니다. 분석 결과의 config가 요청과 다르면 ValueError입니다. cases는 순서대로 결과 목록, passed는 모든 consistent가 True인지, measured는 False인 dict를 반환합니다. 설정 오류에는 출력 폴더도 만들지 않으며 빈 기존 폴더도 덮지 않습니다.
analyze.py --configs <JSON 목록 경로> --out <새 폴더>CLI를 작성합니다. campaign을 실행하고 반환 객체를 report.json과 stdout에 같은 JSON으로 출력합니다. passed=True이면 종료 0, False이면 2이며 보고서는 남깁니다. 설정·파일 오류에는 0 이외로 종료하고 stderr에 원인을 남깁니다. 각 case-NN의 config.json, circuit.cir, ngspice.log, trace.tsv를 보존하고 기존 결과나 빈 기존 출력 폴더를 재사용하지 마세요.
참고
모든 구현은 /root/tdr-location/analyze.py에 저장합니다. 추가 설치·인터넷·실제 장비는 필요 없습니다.
제공 도우미는 /opt/lab/fixtures/tdr_location/simulator.py이며 config 검증과 회로 생성·실제 실행만 수행합니다.
다음처럼 PYTHONPATH를 지정하면 코드의 from simulator import capture가 동작합니다.
PYTHONPATH=/opt/lab/fixtures/tdr_location python3 /root/tdr-location/analyze.py --configs /opt/lab/fixtures/tdr_location/cases.json --out /root/tdr-location/run-01
도우미 capture(config,새폴더)는 Path를 반환하고 config.json·circuit.cir·ngspice.log·trace.tsv를 남깁니다. 잘못된 설정은 실행 전에 거절합니다. 기존 폴더를 거절하므로 재실행에는 run-02처럼 새 이름을 사용하세요. 기본 cases.json은 TD 2/3/4ns × Z2 25/50/100Ω의 9조건이며 rise_ns=0.2입니다.
6단계 consistent의 조건은 모두 동시에 만족해야 합니다. 출발 시각이 있고 A와 0.5V의 차이가 1e-6V 이하, 관측 gamma와 (tail_ohm−50)/(tail_ohm+50)의 차이가 1e-6 이하, echo가 tail_ohm!=50과 같아야 합니다. 설정상 반사가 있으면 두 교차가 있고 관측 왕복 시간과 2*lead_ns의 차이가 0.02ns 이하여야 합니다. 설정상 반사가 없으면 return_ns가 None이어야 합니다. 모델 불일치도 관측값을 지우지 않고 consistent=False로 남깁니다.
ngspice 원시 파일은 시간 단위 s인 time v(tx) 두 열 TSV입니다. 분석 반환 시각은 ns, 거리는 m입니다.
파형·설정은 읽기만 합니다. analyze.py는 일반 파일 64KiB 이하, import는 무출력이어야 합니다.
채점은 작은 별도 표본과 4개 실제 회로 조건(느린 에지 포함)을 실행하며, 수치 허용차는 기본 1e-8,
실제 역산 임피던스 1e-6Ω·시각 0.001ns·거리 0.001m입니다. 부울·None은 정확히 구별합니다.
채점 프로세스는 CPU 12초·파일 8MiB·전체 35초 제한이며 끝나면 하위 프로세스를 정리합니다.
이 실행 제한은 수강 시간과 다릅니다. 강제 종료·출력 누락은 통과가 아닙니다.
실험 조건을 먼저 고정한다
analyze.py의 config(value)를 작성합니다. 객체 키는 lead_ns·tail_ohm·rise_ns만 허용합니다. 값은 각각 2/3/4, 25/50/100, 0.2/0.6 중 하나입니다. bool·문자열·NaN·무한대·누락·추가 키를 ValueError로 거절하고 원본을 바꾸지 않은 새 dict를 반환하세요. import만으로 실행하거나 출력하지 마세요.
bool은 Python에서 int의 하위 타입입니다. 타입을 명시적으로 검사하고 모든 필드가 유한한 허용 수치인지 확인하세요.
초를 ns로 바꾸고 잘린 파형을 거절한다
read_trace(path)는 2MiB 이하의 time v(tx) 헤더를 가진 공백 구분 TSV를 읽어 [(time_ns,voltage_v),...]를 반환합니다. 두 열 모두 유한 수치, 시간은 0 이상 엄격 증가여야 합니다. 최소 100행, 첫 시각 0, 마지막 시각 16ns(오차 1e-9ns 이하)가 필요합니다. 손상·부족 데이터는 ValueError이며 파일을 수정하지 않습니다. 최초 파일의 time 단위는 s입니다.
헤더와 행 길이를 먼저 확인합니다. 1e9 변환은 한 번만 하며 중복 시각도 거절합니다. 마지막 행을 확인하지 않으면 부분 출력이 완성 결과처럼 보입니다.
두 평탄부를 다른 창에서 읽는다
plateaus(rows)는 ns/V 두 열의 목록을 받아 닫힌 창 [2,3]ns의 중앙값 launch_v와 [12,14]ns의 중앙값 settled_v를 반환합니다. 각 창에는 최소 두 점이 필요합니다. 행은 둘 이상, 시각은 0 이상 엄격 증가, 값은 불리언이 아닌 유한 숫자여야 하며 부족·손상은 ValueError입니다. 원본 행은 변경하지 마세요.
전체 파형의 평균이나 두 끝값 평균이 아닙니다. 창 경계의 표본도 포함하고 표본이 홀수일 때와 짝수일 때 모두 중앙값 규약을 따릅니다.
음의 반사도 임피던스로 되돌린다
reflection(launch_v,settled_v)는 gamma=(B-A)/A와 z_ohm=50*(1+gamma)/(1-gamma)를 반환합니다. 입력은 유한 숫자이며 bool 금지입니다. A>0, -1
B/A는 원래 진행파까지 포함한 비율입니다. B-A로 반사 성분을 분리해야 하며 절댓값으로 음의 반사를 지우지 않습니다.
올라가는 에지와 내려가는 에지를 보간한다
crossing(rows,threshold_v,after_ns,direction)는 direction=정수 1 또는 -1의 첫 교차 시각 ns를 반환합니다. 상승은 a.vthreshold>=b.v인 구간을 선형 보간하고, 결과 시각>=after_ns인 첫 사건을 선택합니다. 없으면 None입니다. rows는 3단계와 같은 유효성 조건, after_ns는 유한 0 이상, 임계값은 유한 수치입니다. 잘못된 값·bool 방향은 ValueError입니다.
after_ns가 구간 안에 있어도 보간 결과가 조건을 만족하면 유효합니다. 시작점이 이미 높은 경우나 평탄부 자체는 새 교차로 세지 않습니다.
실제 파형에서 경계의 위치를 읽는다
analyze(folder)는 config.json과 trace.tsv를 읽고 config, launch_v, settled_v, gamma, z_ohm, launch_ns, return_ns, distance_m, echo, consistent, simulated, physical_certified를 반환합니다. 출발은 A/2 상승 교차, 반사가 있으면 귀환은 after=3ns의 (A+B)/2 교차(부호 방향)입니다. echo는 |gamma|>1e-6이며 아니면 귀환·거리 모두 None입니다. 거리는 0.2*(귀환-출발)/2m입니다. 시각이 없으면 거리도 None입니다. simulated=True, physical_certified=False를 지킵니다. 일치 기준은 아래 참고를 따릅니다.
설정 lead_ns를 그대로 거리로 쓰지 말고 관측한 두 교차 시각을 사용하세요. 반사 없는 경우에는 설정에 경계가 있어도 관측 위치를 만들지 않습니다.
모든 설정을 검증한 다음 실행한다
campaign(values,folder)는 서로 중복되지 않는 1~12개 설정의 list 전체를 사전 검증한 뒤 새 폴더를 만듭니다. 각 설정으로 제공된 simulator.capture(config,folder/case-NN)를 실행하고 analyze로 분석합니다. NN은 입력 순서의 두 자리 00부터입니다. 분석 결과의 config가 요청과 다르면 ValueError입니다. cases는 순서대로 결과 목록, passed는 모든 consistent가 True인지, measured는 False인 dict를 반환합니다. 설정 오류에는 출력 폴더도 만들지 않으며 빈 기존 폴더도 덮지 않습니다.
첫 설정만 검증하고 실행하면 뒤 설정이 틀렸을 때 부분 결과가 생깁니다. 제공 모듈 경로는 PYTHONPATH로 연결하고 관측 폴더의 설정을 요청과 다시 비교합니다.
보고서와 원본 증거를 남긴다
analyze.py --configs <JSON 목록 경로> --out <새 폴더> CLI를 작성합니다. campaign을 실행하고 반환 객체를 report.json과 stdout에 같은 JSON으로 출력합니다. passed=True이면 종료 0, False이면 2이며 보고서는 남깁니다. 설정·파일 오류에는 0 이외로 종료하고 stderr에 원인을 남깁니다. 각 case-NN의 config.json, circuit.cir, ngspice.log, trace.tsv를 보존하고 기존 결과나 빈 기존 출력 폴더를 재사용하지 마세요.
실행 코드는 name 가드 아래에 둡니다. 보고서만 출력하고 원본 파형을 버리면 재검토할 수 없습니다. 예외를 성공으로 바꾸지 않습니다.