Skip to content

Revive DIII-D get_n1_bradial_parameters#500

Open
yumouwei wants to merge 19 commits intodevfrom
wei/d3d-onsbradial
Open

Revive DIII-D get_n1_bradial_parameters#500
yumouwei wants to merge 19 commits intodevfrom
wei/d3d-onsbradial

Conversation

@yumouwei
Copy link
Copy Markdown
Contributor

@yumouwei yumouwei commented Dec 18, 2025

Implemented changes

  • Reimplement D3DPhysicsMethods.get_n1_bradial_parameters. This method was previously moved to drafts/machine/d3d/physics.py in v0.8 (Add docstrings for modules/classes/methods #325) and later removed alongside all other draft scripts in v0.11 (Remove draft scripts #420).
  • Create D3DPhysicsMethods.get_btor and use it in get_n1_bradial_parameters and get_n1rms.
  • These new physics methods return n_equal_1_mode, n_equal_1_normalized (tested & XFAIL), and btor (not tested)

Notes on testing

  • n_equal_1_mode and n_equal_1_normalized are both marked as XFAIL as all 4 testing shots fall within the range of shots where the raw signal data need to be retrieved from files previously stored on iris.
  • I have checked these two signals with the last shot (177061) in the DISRUPTION_WARNING table and the outputs from this physics method match the data in the table.
  • The outputs for shot 175552 (referenced in Nucl. Fusion 59 (2019) 096016) do not match the stored data in the DISRUPTION_WARNING table. I found out that these stored data match those from the legacy DUD system (fallback data source in the method's logic) instead of the ONFR system which is available for this shot.

Future TODO

@gtrevisan gtrevisan changed the title Revive D3D get_n1_bradial_parameters Revive DIII-D get_n1_bradial_parameters Feb 3, 2026
@gtrevisan gtrevisan added the machine: DIII-D Related to the DIII-D tokamak label Feb 3, 2026
@gtrevisan gtrevisan marked this pull request as draft February 6, 2026 14:59
@yumouwei yumouwei force-pushed the wei/d3d-onsbradial branch from 1107210 to 19f6fd6 Compare March 11, 2026 14:46
@yumouwei yumouwei marked this pull request as ready for review April 21, 2026 15:46
Comment thread disruption_py/machine/d3d/physics.py
Comment thread disruption_py/machine/d3d/physics.py
Comment thread disruption_py/machine/d3d/physics.py Outdated
@gtrevisan gtrevisan requested a review from ZanderKeith April 21, 2026 16:04
@gtrevisan
Copy link
Copy Markdown
Member

@ZanderKeith, do you have some time to take a look?

Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py
Comment thread disruption_py/machine/d3d/physics.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reintroduces DIII-D physics support for n=1 B-radial parameters by reimplementing D3DPhysicsMethods.get_n1_bradial_parameters and factoring out a reusable toroidal-field helper.

Changes:

  • Added D3DPhysicsMethods.get_btor to retrieve/interpolate toroidal field (btor).
  • Reimplemented get_n1_bradial_parameters to fetch ONFR/DUD bradial signals and compute normalized n=1 amplitude.
  • Updated get_n1rms_parameters to use get_btor for normalization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py
Comment thread disruption_py/machine/d3d/physics.py Outdated
Copy link
Copy Markdown
Contributor

@ZanderKeith ZanderKeith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Methods look correct physics-wise. Ran them for a few shots from our recent DIII-D campaign with significant MHD activity. Signals line up well with those in reviewplus.

I'd still like to know what dusbradial vs onsbradial mean (and perhaps have a comment noting the difference), but other than that looks good to me.

@gtrevisan
Copy link
Copy Markdown
Member

gtrevisan commented Apr 29, 2026

I ran:

./scripts/disruption-errors.sh disruption_warning \
-m get_btor -m get_n1_bradial_parameters -m get_n1rms_parameters 

it "only" raised NotImplementedError... but for 10,797 shots out of 13,245 -- is this expected? at this scale?

@yumouwei
Copy link
Copy Markdown
Contributor Author

I just checked the d3d disruption_warning table for the number of shots within the NotImplementedError ranges, and it matches exactly with what you got.

SELECT COUNT(DISTINCT SHOT) AS shot_count
FROM disruption_warning
WHERE (SHOT BETWEEN 156199 AND 172430)
   OR (SHOT BETWEEN 176030 AND 176912)

SELECT COUNT(DISTINCT SHOT) AS total_shot_count
FROM disruption_warning

> shot_count = 10,797 , total_shot_count = 13,245

So yeah it's a lot of shots.

Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py Outdated
Comment thread disruption_py/machine/d3d/physics.py Outdated
n_equal_1_mode = tree.getNode("dusbradial").data().squeeze() # [G]
t_n1 = tree.getNode("dusbradial").dim_of().data() # [ms]
finally:
tree.close()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure you want the tree closing operation in the finally block... I'd just put it as a last thing in the try block, otherwise you will raise exceptions if eg the tree does not exist.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICS we have custom recalc trees for 3,814 shots out of the total 16,232 in the specified range -- 12,418 are missing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is consistent with the docstring in the MATLAB script

% 2019/04/05 - CR: This routine will not find any dusbradial or onsbradial
% data in the "standard" (atlas) tree paths for certain
% discharges. In September 2017, I went through the
% existing 2014-2017 SQL database discharges and found
% that 3814 shots were missing the bradial calculation.
% B. Sammuli recomputed the missing bradial from the
% existing ESLDs and stored the info as MDS data, in
% tree structures for the specified shot numbers.
% The actual data is stored in
% /fusion/projects/disruption_warning/recalc_bradial
% and /fusion/projects/codes/pcs/data/mdsdata/bradial

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For that finally block, I was worrying if e.g. the tree.getNode statement raises an error and terminates this method, then this opened tree will never be closed. I don't know if the garbage collector does this automatically.

)
filename = config("d3d").physics.bradial_path.recalc_nc
ds = xr.open_dataset(filename)
shot_data = ds.sel(shot=params.shot_id)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does that exist for all shots in the range, or should we check for existence and possibly catch KeyErrors and reraise them as our upcoming custom exceptions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICS these 4 shots (between 176030 and 176912) are not included in the .nc file:

  • 176108 176209 176226 176227

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should raise an FetchDataError here to make it consistent with the behavior of xr.py.

Comment thread disruption_py/machine/d3d/physics.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

machine: DIII-D Related to the DIII-D tokamak

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants