-
Notifications
You must be signed in to change notification settings - Fork 4
Add three new C-Mod physics methods with H-mode related variables #562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
be8fec5
d936a98
636d1af
ce027e4
a203588
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -81,6 +81,16 @@ imas = "/summary/global_quantities/greenwald_fraction/value" | |
| units = "dimensionless" | ||
| validity = [0, 1.5] | ||
|
|
||
| [cmod.physics.attributes.h98] | ||
| description = "H98 confinement enhancement factor." | ||
| units = "dimensionless" | ||
| validity = [0.05, 1.75] | ||
|
|
||
| [cmod.physics.attributes.h_alpha] | ||
| description = "H-alpha line emission intensity." | ||
| units = "W/(m2*sr)" | ||
| validity = [0.0, 161.920898] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imas? |
||
|
|
||
| [cmod.physics.attributes.i_efc] | ||
| description = "Error field correction (EFC) coil current." | ||
| units = "A" | ||
|
|
@@ -180,6 +190,11 @@ imas = "/bolometer/power_radiated_total" | |
| units = "W" | ||
| validity = [0, inf] | ||
|
|
||
| [cmod.physics.attributes.pow_thr_LH_Martin] | ||
| description = "Martin 2008 L-H transition power threshold scaling." | ||
| units = "W" | ||
| validity = [0, 0.1e8] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imas? |
||
|
|
||
| [cmod.physics.attributes.prad_peaking] | ||
| description = "Peaking factor of the radiated power." | ||
| units = "dimensionless" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,7 @@ | |
| interp1, | ||
| ) | ||
| from disruption_py.inout.mds import mdsExceptions | ||
| from disruption_py.machine.cmod.efit import CmodEfitMethods | ||
| from disruption_py.machine.cmod.thomson import CmodThomsonDensityMeasure | ||
| from disruption_py.machine.tokamak import Tokamak | ||
|
|
||
|
|
@@ -2106,3 +2107,167 @@ def _is_on_blacklist(shot_id: int) -> bool: | |
| or 1150000000 < shot_id < 1150610000 | ||
| or 1160000000 < shot_id < 1160303000 | ||
| ) | ||
|
|
||
| @staticmethod | ||
| @physics_method(columns=["h_alpha"], tokamak=Tokamak.CMOD) | ||
| def get_h_alpha(params: PhysicsMethodParams): | ||
| """ | ||
| Get the H_alpha line emission intensity. | ||
|
|
||
| The intensity of H-alpha radiance indicates presence of ELMs, and/or | ||
| radiative events, and changes of confinement regimes. | ||
|
|
||
| In case of using this signal for ELM detection, it is recommended to | ||
| use the native time base of the signal to avoid loosing ELMs. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| params : PhysicsMethodParams | ||
| The parameters containing the MDSplus connection, shot id and more. | ||
|
|
||
| Returns | ||
| ------- | ||
| dict | ||
| A dictionary with the H-alpha signal (`h_alpha`). In IS brightness units [W/(m2*sr)]. | ||
|
|
||
|
Comment on lines
+2120
to
+2132
|
||
| Last major update by Enrique Zapata zapata_e@mit.edu | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you might want to reference this very PR -- take a look at the other docstrings for inspiration/formatting.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would remove the "Last major update..." line and add the "References" block like other physics methods. |
||
| """ | ||
| output = { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think you need this: any unhandled exception will result in returning NaNs. |
||
| "h_alpha": [np.nan], | ||
| } | ||
| # Get signals from SPECTROSCOPY tree | ||
| try: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you do not need the try block, the framework will catch and dump any exception as needed. |
||
| h_alpha, time_halpha = params.data_conn.get_data_with_dims( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should be able to invoke |
||
| r"\SPECTROSCOPY::HA_2_BRIGHT", group="SPECTROSCOPY" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. although |
||
| ) # [mW/(cm2*sr)], [s] | ||
| # Interpolate Halpha to params.times | ||
| h_alpha_interp = interp1(time_halpha, h_alpha, params.times) | ||
| output["h_alpha"] = 10 * h_alpha_interp # [W/(m2*sr)] | ||
| except ValueError as e: | ||
| params.logger.warning("Failed to get H_alpha signal. Returning NaNs.") | ||
| params.logger.opt(exception=True).debug(e) | ||
|
Comment on lines
+2146
to
+2148
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this Since the method will just return |
||
| return output | ||
|
Comment on lines
+2138
to
+2149
|
||
|
|
||
| @staticmethod | ||
| @physics_method(columns=["h98"], tokamak=Tokamak.CMOD) | ||
| def get_h98(params: PhysicsMethodParams): | ||
| """ | ||
| Compute H98 by getting tau_E | ||
|
|
||
| Parameters | ||
| ---------- | ||
| params : PhysicsMethodParams | ||
| The parameters containing the MDSplus connection, shot id and more. | ||
|
|
||
| Returns | ||
| ------- | ||
| dict | ||
| A dictionary with the H98 confinement enhancement factor (`h98`), which is dimensionless | ||
|
|
||
| References | ||
| ---------- | ||
| Scaling from eq. 20, ITER Physics Basis Chapter 2 | ||
| https://iopscience.iop.org/article/10.1088/0029-5515/39/12/302/pdf | ||
|
Comment on lines
+2167
to
+2170
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would make sure the format here is consistent with the References section in other physics methods' docstring. We've never referenced materials outside the disruption-py repo before; I think we can put this as a standalone bullet point and put the URL to a hyperlink, so something like this: |
||
|
|
||
| Original Author: Andrew Maris (maris@mit.edu) | ||
| Last major update by Enrique Zapata (zapata_e@mit.edu) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you might want to reference this very PR -- take a look at the other docstrings for inspiration/formatting. |
||
| """ | ||
|
|
||
| # Get parameters for calculating confinement time | ||
| powers_df = CmodPhysicsMethods.get_power(params=params) | ||
| efit_df = CmodEfitMethods.get_efit_parameters(params=params) | ||
| density_df = CmodPhysicsMethods.get_densities(params=params) | ||
| ip_df = CmodPhysicsMethods.get_ip_parameters(params=params) | ||
|
Comment on lines
+2177
to
+2180
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| # Get btor | ||
| btor, t_mag = params.data_conn.get_data_with_dims( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. drop |
||
| r"\btor", group="magnetics" | ||
| ) # tmag: [s] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. at this point mention units for both quantities, here, I guess T and s. |
||
| # Toroidal power supply takes time to turn on, from ~ -1.8 and should be | ||
| # on by t=-1. So pick the time before that to calculate baseline | ||
| baseline_indices = np.where(t_mag <= -1.8) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't you need a comma, here? please double check dimensions. |
||
| btor = btor - np.mean(btor[baseline_indices]) | ||
| btor = np.abs(interp1(t_mag, btor, params.times)) | ||
|
|
||
| # Get signals | ||
| ip = np.abs(ip_df.get("ip")) / 1.0e6 # [A] -> [MA] | ||
| n_e = density_df.get("n_e") / 1.0e19 # [m^-3] -> [10^19 m^-3] | ||
| p_input = powers_df.get("p_input") / 1.0e6 # [W] -> [MW] | ||
| dwmhd_dt = efit_df.get("dwmhd_dt") / 1.0e6 # [W] -> [MW] | ||
|
Comment on lines
+2193
to
+2196
|
||
| wmhd = efit_df.get("wmhd") / 1.0e6 # [J] -> [MJ] | ||
| r0 = efit_df.get("rmagx") # [m] | ||
| a_minor = efit_df.get("a_minor") # [m] | ||
| epsilon = a_minor / r0 | ||
| kappa = efit_df.get("kappa") | ||
| tau = wmhd / (p_input - dwmhd_dt) | ||
|
|
||
| # Compute 1998 tau_E scaling, taking A (atomic mass) = 2. | ||
| tau_98 = ( | ||
| 0.0562 | ||
| * (np.sign(n_e) * np.abs(n_e) ** 0.41) | ||
| * (2**0.19) | ||
| * (np.sign(ip) * np.abs(ip) ** 0.93) | ||
| * (np.sign(r0) * np.abs(r0) ** 1.97) | ||
| * (np.sign(epsilon) * np.abs(epsilon) ** 0.58) | ||
| * (np.sign(kappa) * np.abs(kappa) ** 0.78) | ||
| * (np.sign(btor) * np.abs(btor) ** 0.15) | ||
| * (np.sign((p_input - dwmhd_dt)) * np.abs((p_input - dwmhd_dt)) ** -0.69) | ||
| ) | ||
| h98 = tau / tau_98 | ||
| h98[h98 <= 0] = 0 | ||
| output = { | ||
| "h98": h98, | ||
| } | ||
| return output | ||
|
|
||
| @staticmethod | ||
| @physics_method(columns=["pow_thr_LH_Martin"], tokamak=Tokamak.CMOD) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd use all lowercase for the signal name to align with the convention.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also just found out that |
||
| def get_itpa_pow_thr(params: PhysicsMethodParams): | ||
| """ | ||
| Power threshold for L-H transition. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| params : PhysicsMethodParams | ||
| The parameters containing the MDSplus connection, shot id and more. | ||
|
|
||
| Returns | ||
| ------- | ||
| dict | ||
| A dictionary with the power threshold for L-H transition | ||
| (`pow_thr_LH_Martin`), in Watts [W] | ||
|
|
||
| References | ||
| ---------- | ||
| Scaling from Y R Martin et al 2008 J. Phys.: Conf. Ser. 123 012033 | ||
| DOI 10.1088/1742-6596/123/1/012033 | ||
|
|
||
| Last major update by Enrique Zapata | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above. |
||
| """ | ||
|
|
||
| density_df = CmodPhysicsMethods.get_densities(params=params) | ||
| areao_df = CmodPhysicsMethods.get_kappa_area(params=params) | ||
|
|
||
| # Get BT | ||
| btor, t_mag = params.data_conn.get_data_with_dims( | ||
| r"\btor", group="magnetics" | ||
| ) # tmag: [s] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above. |
||
| # Toroidal power supply takes time to turn on, from ~ -1.8 and should be | ||
| # on by t=-1. So pick the time before that to calculate baseline | ||
| baseline_indices = np.where(t_mag <= -1.8) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above. |
||
| btor = btor - np.mean(btor[baseline_indices]) | ||
| btor = np.abs(interp1(t_mag, btor, params.times)) # [T] | ||
|
Comment on lines
+2251
to
+2259
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might want to distill the btor computation in I do realize this suggestion is contradictory with my suggestion in R2180 so take this with a grain of salt. |
||
| n_e = density_df.get("n_e") / 1.0e20 # [m^-3] -> [10^20 m^-3] | ||
| areao = areao_df.get("kappa_area") # [m^2] | ||
|
|
||
|
Comment on lines
+2248
to
+2262
|
||
| # Estimate power threshold. | ||
| itpa_power_thr = ( | ||
| 0.0488 | ||
| * (np.sign(n_e) * np.abs(n_e) ** 0.717) | ||
| * (np.sign(btor) * np.abs(btor) ** 0.803) | ||
| * (np.sign(areao) * np.abs(areao) ** 0.941) | ||
| ) | ||
| output = { | ||
| "pow_thr_LH_Martin": 1e6 * itpa_power_thr, | ||
| } | ||
| return output | ||
|
Comment on lines
+2270
to
+2273
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can just do |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imas?