TT Lab
はじめる
学ぶ 学習パス コース

ケーブルがこだまする

TDR:反射の極性と往復遅延で位置を求める

TT Labで続きを見る

目標

反射の符号と往復の遅延から、インピーダンスの境界を1つ復元します。反射のない場合は、位置を観測できないものとして残します。

目安は80分です。基本セッションの60分が終わる前に、+時間で延長してください(最大180分)。 Podのファイルは、終了すると消えます。ソースと結果は、終了前に別に保管してください。 前提知識は、前のシグナルインテグリティのラボ、Pythonの関数・リスト・JSON・ファイル処理です。

なぜ重要なのか

値が正しく見えても、反射の符号・時間の原点・往復の区間を混ぜると、別の境界を報告してしまいます。 設定に書いた位置をそのまま結果に書くミスと、反射のない波形から位置を作り出すミスを、 あわせて防ぎます。回路は理想的な単一モードの無損失線路で、実物の計測・認証の代わりにはなりません。

ステップ

  1. 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しただけで実行したり、出力したりしないでください。
  2. read_trace(path)は、2MiB以下の、time v(tx)のヘッダーを持つ空白区切りのTSVを読み、[(time_ns,voltage_v),...]を返します。2つの列とも有限の数値で、時間は0以上で厳密に増加している必要があります。最低100行、最初の時刻は0、最後の時刻は16ns(誤差1e-9ns以下)が必要です。破損・不足したデータはValueErrorで、ファイルは修正しません。最初のファイルのtimeの単位はsです。
  3. plateaus(rows)は、ns/Vの2つの列のリストを受け取り、閉じた窓[2,3]nsの中央値launch_vと、[12,14]nsの中央値settled_vを返します。それぞれの窓には、少なくとも2点が必要です。行は2つ以上、時刻は0以上で厳密に増加、値はブールではない有限の数でなければならず、不足・破損はValueErrorです。元の行は変更しないでください。
  4. reflection(launch_v,settled_v)は、gamma=(B-A)/Aとz_ohm=50*(1+gamma)/(1-gamma)を返します。入力は有限の数で、boolは禁止です。A>0、-1
  5. 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です。
  6. 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を守ります。一致の基準は、下の参考に従います。
  7. campaign(values,folder)は、互いに重複しない1–12個の設定のlist全体を事前に検証したあと、新しいフォルダーを作ります。それぞれの設定で、提供されたsimulator.capture(config,folder/case-NN)を実行し、analyzeで分析します。NNは入力順の2桁の00からです。分析結果のconfigが要求と異なればValueErrorです。casesは順番どおりの結果のリスト、passedはすべてのconsistentがTrueかどうか、measuredはFalseのdictを返します。設定のエラーでは出力フォルダーも作らず、空の既存のフォルダーも上書きしません。
  8. analyze.py --configs <JSON 목록 경로> --out <새 폴더>のCLIを作成します(プレースホルダーはJSONリストのパスと新しいフォルダーです)。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つの交差があり、観測した往復の時間と2*lead_nsの差が0.02ns以下でなければなりません。 設定上で反射がないなら、return_nsがNoneでなければなりません。モデルと一致しない場合も、観測値を消さずにconsistent=Falseとして残します。

ngspiceの生のファイルは、時間の単位がsのtime v(tx)の2列の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),...]を返します。2つの列とも有限の数値で、時間は0以上で厳密に増加している必要があります。最低100行、最初の時刻は0、最後の時刻は16ns(誤差1e-9ns以下)が必要です。破損・不足したデータはValueErrorで、ファイルは修正しません。最初のファイルのtimeの単位はsです。

ヘッダーと行の長さを先に確認します。1e9の変換は1回だけ行い、重複した時刻も拒否します。最後の行を確認しないと、部分的な出力が完成した結果のように見えます。

2つの平坦部を別の窓で読む

plateaus(rows)は、ns/Vの2つの列のリストを受け取り、閉じた窓[2,3]nsの中央値launch_vと、[12,14]nsの中央値settled_vを返します。それぞれの窓には、少なくとも2点が必要です。行は2つ以上、時刻は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をそのまま距離に使わず、観測した2つの交差の時刻を使ってください。反射のない場合は、設定に境界があっても、観測した位置を作り出してはいけません。

すべての設定を検証してから実行する

campaign(values,folder)は、互いに重複しない1–12個の設定のlist全体を事前に検証したあと、新しいフォルダーを作ります。それぞれの設定で、提供されたsimulator.capture(config,folder/case-NN)を実行し、analyzeで分析します。NNは入力順の2桁の00からです。分析結果のconfigが要求と異なればValueErrorです。casesは順番どおりの結果のリスト、passedはすべてのconsistentがTrueかどうか、measuredはFalseのdictを返します。設定のエラーでは出力フォルダーも作らず、空の既存のフォルダーも上書きしません。

最初の設定だけを検証して実行すると、あとの設定が誤っていたときに、部分的な結果が生じます。提供されたモジュールのパスはPYTHONPATHでつなぎ、観測フォルダーの設定を要求と比べ直します。

報告書と元の証拠を残す

analyze.py --configs <JSON 목록 경로> --out <새 폴더>のCLIを作成します(プレースホルダーはJSONリストのパスと新しいフォルダーです)。campaignを実行し、返されたオブジェクトをreport.jsonとstdoutに、同じJSONで出力します。passed=Trueなら終了コード0、Falseなら2で、報告書は残します。設定・ファイルのエラーでは0以外で終了し、stderrに原因を残します。それぞれのcase-NNのconfig.json、circuit.cir、ngspice.log、trace.tsvを保存し、既存の結果や空の既存の出力フォルダーを再利用しないでください。

実行するコードは、__name__のガードの下に置きます。報告書だけを出力して元の波形を捨てると、再検討できません。例外を成功に変えてはいけません。