ピン容量で失われた帯域幅
目標
集中定数のRC回路の実際のAC応答から、相対的な帯域幅と位相を抽出し、6つの条件を比べます。 Pythonの関数・複素数・リスト・JSON・分圧の基礎が必要です。目安は80分なので、基本の60分が終わる前に、+時間で延長してください(最大180分)。セッションが終わるとファイルは消えるので、別に保管してください。
なぜ重要なのか
入力ピンの負荷を抵抗だけで見ると見落とす、周波数への依存性を学びます。絶対的な電圧の分圧と、通過帯域に対する減衰、大きさと位相、実行の成功と規格への合格を、それぞれ区別します。 理想的な集中定数のRCモデルで、長い伝送線路・非線形のピン・実物の計測・バスの規格の認証の代わりにはなりません。
ステップ
- すべての実装は、/root/pin-bandwidth/analyze.pyに保存します。predict(config)は、dc_gain, rth_ohm, pole_hzを返します。設定は、source_ohm=10/25/50、load_ohm=50/100、cap_pf=10/20/40のうち1つずつの、ちょうど3つのキーのdictです。数値のint/floatだけを受け付け、bool・文字列・欠落・追加のキー・範囲外の値はValueErrorです。元のオブジェクトは変えません。DCの分圧、並列の等価抵抗、1/(2πRthC)を計算してください。
- read_response(path)は、ヘッダーがfrequency hre himの空白区切りのファイルを読み、(Hz,実部,虚部)のタプルのリストを返します。1MiB以下の通常のファイル、データ2行以上、行ごとに有限の数が3つ、周波数は正で厳密に増加していることを検査し、違反はValueErrorで拒否します。秒やMHzには変換しません。ヘッダーの前後の空白は許可します。
- metrics(rows)は、有効な(Hz,実部,虚部)のリストを受け取り、各行のhz, magnitude, db, phase_degのオブジェクトのリストを返します。大きさは複素数の絶対値、dbは20log10(大きさ)、位相はatan2の度の単位で、範囲は−180–180度です。大きさが0ならValueErrorです。すべての入力の行と順序を保ってください。
- bandwidth(points,dc_gain)は、有効なmetricsの結果と、正のDCゲインを受け取ります。しきい値は20log10(dc_gain)−10log10(2)です。a.db > しきい値 >= b.dbとなる最初の隣り合う区間で、dB対log10(Hz)を線形補間してHzを返してください。交差がなければNoneで、最初からしきい値以下であることを交差とみなしません。
- at_frequency(rows,hz)は、有効な複素応答の表から、hzのcomplexの値を返します。正確なサンプルならその値を使い、間にあるなら、log(周波数)の軸での比率で、実部と虚部をそれぞれ線形補間します。表の範囲を外れるとValueErrorです。大きさや位相を別々に補間する関数ではありません。
- analyze(folder)は、config.jsonとresponse.tsvを読み、下の参考の結果のオブジェクトを返します。全体の161行・1MHz–10GHz・40点/decadeのグリッドを検査し、足りない場合や異なる場合はValueErrorです(周波数の相対誤差1e-9)。帯域幅・100MHzでの相対ゲインと位相は表から求め、すべての複素サンプルをH0/(1+jf/fc)と比べます。モデルと一致しない場合も、観測値は残します。
- campaign(values,folder)は、重複のない1–18個の設定のlist全体をpredictで検証したあと、新しいフォルダーを作ります。提供されたsimulator.capture(config,folder/case-NN)で、各条件を実行してanalyzeします。NNは入力順の00からで、観測したconfigが要求と異なればValueErrorです。resultsのリスト、すべてのpassedがTrueかどうかを表すall_pass、model=lumped_rc、measured=Falseを返し、同じオブジェクトをreport.jsonに保存します。既存のフォルダーは、空でも拒否します。設定のエラーでは、フォルダーも作りません。
参考
実装のパスは/root/pin-bandwidth/analyze.pyです。インターネット・追加パッケージ・機器は必要ありません。 提供されるヘルパー/opt/lab/fixtures/pin_bandwidth/simulator.pyは、回路の生成と、実際のngspiceの実行だけを行います。 Rsが直列、RLとCが並列の回路にAC 1Vを入れ、1MHz–10GHzをdecadeあたり40点で計算します。 capture(config,新しいフォルダー)はPathを返し、既存の結果を上書きしません。入力のCの単位はpFです。
ステップ6の戻りのキーは、config, bandwidth_hz, relative_db, phase_deg, max_complex_error, consistent, meets_spec, passed, measuredです。relative_dbは、100MHzでの 20log10(|H|/H0)で、phase_degは、同じ補間したHの位相です。max_complex_errorは、すべての行の 観測したHとモデルのHの差の絶対値の最大値です。consistentは、この誤差が1e-8以下で、 観測した帯域幅が存在し、予測したfcに対する誤差が0.2%以下のときだけTrueです。 meets_specは、観測した帯域幅が200MHz以上、relative_dbが−0.5dB以上、phase_degが−20度以上を 同時に満たすときにTrueです。passedは、consistentとmeets_specの両方がTrueかどうかで、measuredはFalseです。 交差がなく、帯域幅がNoneなら、consistent・meets_spec・passedはFalseです。観測そのものは、捨てません。
ステップ7の実装のあと、次のコマンドで、ソース25/50Ω × C 10/20/40pF、負荷50Ωの6つの条件を実行してください。 失敗する条件が含まれるので、正常な報告書のall_passはFalseです。再実行には、新しい出力フォルダーの名前を使ってください。
cd /root/pin-bandwidth
PYTHONPATH=/opt/lab/fixtures/pin_bandwidth python3 - <<'PY'
from analyze import campaign
conditions = [dict(source_ohm=r, load_ohm=50, cap_pf=c) for r in (25,50) for c in (10,20,40)]
report = campaign(conditions, '/root/pin-bandwidth/run-01')
print(report)
PY
ソースは64KiB以下の通常のファイルで、importしたときは何も出力してはいけません。波形・設定は、読むだけにしてください。 採点は、別の小さなサンプルと実際のエンジンを使い、一般的な数値の許容誤差は、相対・絶対とも1e-8です。 採点のプロセスは、CPU 12秒・出力ファイル8MiB・全体で35秒の上限です。受講時間とは異なります。
分圧と極を予測する
すべての実装は、/root/pin-bandwidth/analyze.pyに保存します。predict(config)は、dc_gain, rth_ohm, pole_hzを返します。設定は、source_ohm=10/25/50、load_ohm=50/100、cap_pf=10/20/40のうち1つずつの、ちょうど3つのキーのdictです。数値のint/floatだけを受け付け、bool・文字列・欠落・追加のキー・範囲外の値はValueErrorです。元のオブジェクトは変えません。DCの分圧、並列の等価抵抗、1/(2πRthC)を計算してください。
pFをFに変換し、電圧源を0にしたときにコンデンサーが見る2つの抵抗を考えてください。
複素応答の表を読む
read_response(path)は、ヘッダーがfrequency hre himの空白区切りのファイルを読み、(Hz,実部,虚部)のタプルのリストを返します。1MiB以下の通常のファイル、データ2行以上、行ごとに有限の数が3つ、周波数は正で厳密に増加していることを検査し、違反はValueErrorで拒否します。秒やMHzには変換しません。ヘッダーの前後の空白は許可します。
隣り合う2つの行の周波数が同じ場合も、拒否します。分析は、生のファイルを修正しません。
大きさと位相を分離する
metrics(rows)は、有効な(Hz,実部,虚部)のリストを受け取り、各行のhz, magnitude, db, phase_degのオブジェクトのリストを返します。大きさは複素数の絶対値、dbは20log10(大きさ)、位相はatan2の度の単位で、範囲は−180–180度です。大きさが0ならValueErrorです。すべての入力の行と順序を保ってください。
実部は大きさとは異なります。3+4jの大きさと、実部・虚部がともに負の象限を、手で確認してください。
相対的な半電力の周波数を探す
bandwidth(points,dc_gain)は、有効なmetricsの結果と、正のDCゲインを受け取ります。しきい値は20log10(dc_gain)−10log10(2)です。a.db > しきい値 >= b.dbとなる最初の隣り合う区間で、dB対log10(Hz)を線形補間してHzを返してください。交差がなければNoneで、最初からしきい値以下であることを交差とみなしません。
絶対的な−3dBではありません。1MHzと100MHzの間で、dBの差が半分なら、周波数は10MHzです。
同じ周波数で複素数を比べる
at_frequency(rows,hz)は、有効な複素応答の表から、hzのcomplexの値を返します。正確なサンプルならその値を使い、間にあるなら、log(周波数)の軸での比率で、実部と虚部をそれぞれ線形補間します。表の範囲を外れるとValueErrorです。大きさや位相を別々に補間する関数ではありません。
まず対数軸での位置の比率を求めてから、2つの複素数の間を動いてください。両端の点は、外挿ではありません。
観測と規格を別々に検証する
analyze(folder)は、config.jsonとresponse.tsvを読み、下の参考の結果のオブジェクトを返します。全体の161行・1MHz–10GHz・40点/decadeのグリッドを検査し、足りない場合や異なる場合はValueErrorです(周波数の相対誤差1e-9)。帯域幅・100MHzでの相対ゲインと位相は表から求め、すべての複素サンプルをH0/(1+jf/fc)と比べます。モデルと一致しない場合も、観測値は残します。
大きさは同じで位相が誤っているものを捕まえるには、複素数の差の絶対値を比べる必要があります。規格の判定とモデルとの一致を分離してください。
6つの条件の根拠を保存する
campaign(values,folder)は、重複のない1–18個の設定のlist全体をpredictで検証したあと、新しいフォルダーを作ります。提供されたsimulator.capture(config,folder/case-NN)で、各条件を実行してanalyzeします。NNは入力順の00からで、観測したconfigが要求と異なればValueErrorです。resultsのリスト、すべてのpassedがTrueかどうかを表すall_pass、model=lumped_rc、measured=Falseを返し、同じオブジェクトをreport.jsonに保存します。既存のフォルダーは、空でも拒否します。設定のエラーでは、フォルダーも作りません。
失敗した条件も、resultsに残します。captureが作ったconfig.json・circuit.cir・response.tsv・ngspice.logを消さないでください。