Skip to content
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

WHEN and GROUP interaction in 3.x #1807

Open
nicriz opened this issue Dec 17, 2024 · 7 comments
Open

WHEN and GROUP interaction in 3.x #1807

nicriz opened this issue Dec 17, 2024 · 7 comments

Comments

@nicriz
Copy link

nicriz commented Dec 17, 2024

Hi @willend,

I am trying to rerun some old simulations with McStas 3.x and I have noticed a weird behavior when WHEN and GROUP are combined.
I have a simulation where a neutron hit the sample and there are monitors all around. If the neutron goes forward, it can interact with a slit, then the variable hithole is set to 1 and the neutron is recorded by the monitor at 0 deg in the GROUP detectors. Otherwise, if hithole=0 the other detectors of the group are tested.
I followed the guide in here and converted my DECLARE var hithole in USERVAR, but after missing the slit, the neutron is lost and the other detectors are not tested.

If I remove the condition from the first Monitor WHEN (hithole), the group seems to work fine.

McStas Version: 3.5.16 (clean from conda channel)
Linux version 4.18.0-553.5.1.el8_10.x86_64
Working file without WHEN: ND_Reflector.instr.txt
Not working file with WHEN: ND_Reflector_wHit.instr.txt

@willend
Copy link
Contributor

willend commented Dec 17, 2024

Hi @nicriz,

Thanks for reporting this, I confirm to reproduce the issue. As can be the case when combining the various "advanced grammar", something seems to be interacting in a strange way.

What seems to happen is that for any hithole==0 event, the whole group "disappears", as visualised via this instrument file
ND_Reflector_wHit_MonnD_origorder.instr.txt
The only change from yours is use of Monitor_nD to get graphical output:
Screenshot 2024-12-17 at 19 06 41

What interestingly seems to work is if I move the WHEN condition to any non-first element of the group, see this instrument:
ND_Reflector_wHit_MonnD_shiftedorder.instr.txt
which gives this output:
Screenshot 2024-12-17 at 19 07 30

@nicriz
Copy link
Author

nicriz commented Dec 17, 2024

Okay that's a good lead I would say. You may consider this bug report my Christmas gift 😂

Thanks for the workaround, I will try tomorrow. Hopefully the detector's order doesn't mess with my analysis scripts.

Cheers,
Nico

@willend
Copy link
Contributor

willend commented Dec 17, 2024

And here are two other approaches that seems to also work equally well:
(probably since a 'feature' of semi-recent McStas 3.x is that Monitors that do not measure a neutron automatically resets it...)

  1. Leave the WHEN'ed detector out of the group:
    ND_Reflector_wHit_v2.instr.txt
Screenshot 2024-12-17 at 19 19 33
  1. Drop the GROUP detectors all together:
    ND_Reflector_wHit_v3.instr.txt
Screenshot 2024-12-17 at 19 22 39

@willend
Copy link
Contributor

willend commented Dec 17, 2024

Okay that's a good lead I would say. You may consider this bug report my Christmas gift 😂

😂🌲🎁

Thanks for the workaround, I will try tomorrow. Hopefully the detector's order doesn't mess with my analysis scripts.

I wouldn't expect that - but if this is the case, version 2 or 3 above should do the trick. 😜 Geek gift returned! 🎁🤓

@willend
Copy link
Contributor

willend commented Dec 18, 2024

I now know the cause of the problem - and how to solve it generally. 🤓

One set of curly brackets should go in the generated code in the case of WHEN...:

  1. The way the generated code looks around the WHEN'ed monitor today:
    if (!ABSORBED && _particle->_index == 7) {
      _particle->flag_nocoordschange=0; /* Reset if we came here from a JUMP */
      _particle_save = *_particle;
      DEBUG_COMP(_dect1_var._name);
      DEBUG_STATE();
      if ((( hithole ))) // conditional WHEN execution
      class_Monitor_nD_trace(&_dect1_var, _particle);
      if (_particle->_restore)
        particle_restore(_particle, &_particle_save);
      // GROUP detectors: from dect1 [7] to dect11 [17]
      if (SCATTERED) _particle->_index = 17; // when SCATTERED in GROUP: reach exit of GROUP after dect11
      else particle_restore(_particle, &_particle_save); // not SCATTERED in GROUP, restore
      _particle->_index++;
      if (!ABSORBED) { DEBUG_STATE(); }
    } /* end component dect1 [7] */

And what it should look like:

    if (!ABSORBED && _particle->_index == 7) {
      _particle->flag_nocoordschange=0; /* Reset if we came here from a JUMP */
      _particle_save = *_particle;
      DEBUG_COMP(_dect1_var._name);
      DEBUG_STATE();
      if ((( hithole ))) { // conditional WHEN execution <--- CURLY added
	class_Monitor_nD_trace(&_dect1_var, _particle);
	if (_particle->_restore)
	  particle_restore(_particle, &_particle_save);
	// GROUP detectors: from dect1 [7] to dect11 [17]
	if (SCATTERED) _particle->_index = 17; // when SCATTERED in GROUP: reach exit of GROUP after dect11
	else particle_restore(_particle, &_particle_save); // not SCATTERED in GROUP, restore
      }  // <--- CURLY added
      _particle->_index++;
      if (!ABSORBED) { DEBUG_STATE(); }
    } /* end component dect1 [7] */

Result is that we ensure the neutrons get their _particle->_index++ irrespective of state of the WHEN condition and any GROUP scatter consideration.

@nicriz
Copy link
Author

nicriz commented Dec 18, 2024

I now know the cause of the problem - and how to solve it generally. 🤓

One set of curly brackets should go in the generated code in the case of WHEN...:

  1. The way the generated code looks around the WHEN'ed monitor today:
    if (!ABSORBED && _particle->_index == 7) {
      _particle->flag_nocoordschange=0; /* Reset if we came here from a JUMP */
      _particle_save = *_particle;
      DEBUG_COMP(_dect1_var._name);
      DEBUG_STATE();
      if ((( hithole ))) // conditional WHEN execution
      class_Monitor_nD_trace(&_dect1_var, _particle);
      if (_particle->_restore)
        particle_restore(_particle, &_particle_save);
      // GROUP detectors: from dect1 [7] to dect11 [17]
      if (SCATTERED) _particle->_index = 17; // when SCATTERED in GROUP: reach exit of GROUP after dect11
      else particle_restore(_particle, &_particle_save); // not SCATTERED in GROUP, restore
      _particle->_index++;
      if (!ABSORBED) { DEBUG_STATE(); }
    } /* end component dect1 [7] */

And what it should look like:

    if (!ABSORBED && _particle->_index == 7) {
      _particle->flag_nocoordschange=0; /* Reset if we came here from a JUMP */
      _particle_save = *_particle;
      DEBUG_COMP(_dect1_var._name);
      DEBUG_STATE();
      if ((( hithole ))) { // conditional WHEN execution <--- CURLY added
	class_Monitor_nD_trace(&_dect1_var, _particle);
	if (_particle->_restore)
	  particle_restore(_particle, &_particle_save);
	// GROUP detectors: from dect1 [7] to dect11 [17]
	if (SCATTERED) _particle->_index = 17; // when SCATTERED in GROUP: reach exit of GROUP after dect11
	else particle_restore(_particle, &_particle_save); // not SCATTERED in GROUP, restore
      }  // <--- CURLY added
      _particle->_index++;
      if (!ABSORBED) { DEBUG_STATE(); }
    } /* end component dect1 [7] */

Result is that we ensure the neutrons get their _particle->_index++ irrespective of state of the WHEN condition and any GROUP scatter consideration.

Oh that is really interesting. Also the fact that we don't need GROUP anymore for this kind of setting is something I definitely need to keep in mind.

All good with the scripts, probably still bad python, but they held strong 😂

@nicriz nicriz closed this as completed Dec 19, 2024
@willend
Copy link
Contributor

willend commented Dec 19, 2024

I think I will reopen to remind myself to implement the above :)

@willend willend reopened this Dec 19, 2024
willend added a commit that referenced this issue Jan 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants