Setting parameters in the derived fields

Hi all, I'm new to this forum to find some help when setting a new derived field. The situation is that I want to obtain the plane-of-sky components of a vector field (e.g. magnetic field), so I follow (https://yt-project.org/doc/developing/creating_derived_fields.html#a-more-co...) and try something like this for testing my code: def _project_B(field, data): vector = data.get_field_parameter("vector") Bobs = data["gas", "magnetic_field_x"]*vector[0]+data["gas", "magnetic_field_y"]*vector[1]+data["gas", "magnetic_field_z"]*vector[2] return Bobs yt.add_field( ("gas", "project_B"), function=_project_B, sampling_type="cell", units="G", take_log=False, validators=[ValidateParameter(["vector"])], ) npix = 256j ds = yt.load('output_00017/info_00017.txt') sp = ds.r[::npix, ::npix, ::npix] sp.set_field_parameter("vector", yt.YTArray([0., 1., 0.], "dimensionless")) # it can be x/y vector when using off-axis projection Bproj = sp['gas', 'project_B'].value , which returned yt.utilities.exceptions.YTFieldNotFound: Could not find field ('gas', 'project_B') in info_00017 However, if I set "vector" -> "bulk_velocity", it works! Is there something I understand wrong? Best, Wei-An

Hi all, I think I have solved the problem. In case there is anyone who will encounter the same issue in their work, I describe the solution here. The concept is that the field parameter "vector" is not originally presented in our data, so we can't include it when adding a new field and also need to check the existence in _project_B. Therefore, the code will be: def _project_B(field, data): if data.has_field_parameter("vector"): vector = data.get_field_parameter("vector").in_units("dimensionless") else: vector = data.ds.arr(np.array([1, 0, 0]), "dimensionless") Bobs = data["gas", "magnetic_field_x"]*vector[0]+data["gas", "magnetic_field_y"]*vector[1]+data["gas", "magnetic_field_z"]*vector[2] return Bobs yt.add_field( ("gas", "project_B"), function=_project_B, sampling_type="cell", units="G", take_log=False, # validators=[ValidateParameter(["vector"])], ) npix = 256j ds = yt.load('output_00017/info_00017.txt') sp = ds.r[::npix, ::npix, ::npix] sp.set_field_parameter("vector", yt.YTArray([0., 1., 0.], "dimensionless")) Bproj = sp['gas', 'project_B'].value

Hi Wei-An, I'm glad you found a solution to this. I think the reason this is working is that a validation step happens when your field is added with add_field. During this step, a fake grid is passed through your field function to make sure it works. However, I don't think this functionality is able to deal with field parameters that it doesn't already know about, like bulk_velocity or center_of_mass. So what's happening is that the function is failing quietly during this validation because it can't get the vector field parameter and the field does not end up getting added. Making the default vector in your else statement is fixing this. This is something we can probably improve upon in the code. Britton On Thu, Apr 28, 2022 at 3:16 AM We-An Chen <10302leo@gmail.com> wrote:

Hi all, I think I have solved the problem. In case there is anyone who will encounter the same issue in their work, I describe the solution here. The concept is that the field parameter "vector" is not originally presented in our data, so we can't include it when adding a new field and also need to check the existence in _project_B. Therefore, the code will be: def _project_B(field, data): if data.has_field_parameter("vector"): vector = data.get_field_parameter("vector").in_units("dimensionless") else: vector = data.ds.arr(np.array([1, 0, 0]), "dimensionless") Bobs = data["gas", "magnetic_field_x"]*vector[0]+data["gas", "magnetic_field_y"]*vector[1]+data["gas", "magnetic_field_z"]*vector[2] return Bobs yt.add_field( ("gas", "project_B"), function=_project_B, sampling_type="cell", units="G", take_log=False, # validators=[ValidateParameter(["vector"])], ) npix = 256j ds = yt.load('output_00017/info_00017.txt') sp = ds.r[::npix, ::npix, ::npix] sp.set_field_parameter("vector", yt.YTArray([0., 1., 0.], "dimensionless")) Bproj = sp['gas', 'project_B'].value

Hi Wei-An, I'm glad you found a solution to this. I think the reason this is working is that a validation step happens when your field is added with add_field. During this step, a fake grid is passed through your field function to make sure it works. However, I don't think this functionality is able to deal with field parameters that it doesn't already know about, like bulk_velocity or center_of_mass. So what's happening is that the function is failing quietly during this validation because it can't get the vector field parameter and the field does not end up getting added. Making the default vector in your else statement is fixing this. This is something we can probably improve upon in the code. Britton On Thu, Apr 28, 2022 at 3:16 AM We-An Chen <10302leo@gmail.com> wrote:
participants (2)
-
Britton Smith
-
We-An Chen