Skip to content

Instance COPY empty-EXTEND bug #2621

Description

@g5t

In the grammar rules for COMPONENT duplicate = COPY(source)

McCode/mccode/src/instrument.y

Lines 1280 to 1314 in 03e2db0

instref: "COPY" '(' compref ')' actuallist /* make a copy of a previous instance, with def+set */
{
struct comp_inst *comp_src;
struct comp_inst *comp;
comp_src = $3;
palloc(comp);
comp->def = comp_src->def;
comp->extend = comp_src->extend;
comp->group = comp_src->group;
comp->jump = comp_src->jump;
comp->when = comp_src->when;
/* now catenate src and actual parameters */
comp->actuals= symtab_create();
symtab_cat(comp->actuals, $5);
symtab_cat(comp->actuals, comp_src->actuals);
comp->metadata = metadata_list_copy(comp_src->metadata);
$$ = comp;
}
| "COPY" '(' compref ')'
{
struct comp_inst *comp_src;
struct comp_inst *comp;
comp_src = $3;
palloc(comp);
comp->defpar = comp_src->defpar;
comp->setpar = comp_src->setpar;
comp->def = comp_src->def;
comp->extend = comp_src->extend;
comp->group = comp_src->group;
comp->jump = comp_src->jump;
comp->when = comp_src->when;
comp->actuals= comp_src->actuals;
comp->metadata = metadata_list_copy(comp_src->metadata);
$$ = comp;
}

the resulting instance's extend is set to be the same as the source instance.

When translating and compiling the example instrument RTP_Laue.instr warnings are issued to alert the user that a copied component instance's EXTEND block is overwritten:

-----------------------------------------------------------
WARNING: Existing (COPY) EXTEND block in COMPONENT image_plate_eff:
  EXTEND %{
    /* take into account ZnS scintillator efficiency */
    double eff=0.5;
    double v=sqrt(vx*vx+vy*vy+vz*vz);
    p *= 1.0-exp(3960.0/v*log(1.0-eff/100.0));
  %}

is overwritten by:
  EXTEND %{
  %}
-----------------------------------------------------------

-----------------------------------------------------------
WARNING: Existing (COPY) EXTEND block in COMPONENT image_plate_scattered:
  EXTEND %{
    /* take into account ZnS scintillator efficiency */
    double eff=0.5;
    double v=sqrt(vx*vx+vy*vy+vz*vz);
    p *= 1.0-exp(3960.0/v*log(1.0-eff/100.0));
  %}

is overwritten by:
  EXTEND %{
  %}
-----------------------------------------------------------

despite the file not specifying any extra EXTEND on the copies

/* image plate/film with efficiency */
COMPONENT image_plate_ideal = Monitor_nD(xwidth=.3, yheight=.3,
options="x y", bins=1000)
AT (0,0,.1) RELATIVE detector_axis
EXTEND %{
/* take into account ZnS scintillator efficiency */
double eff=0.5;
double v=sqrt(vx*vx+vy*vy+vz*vz);
p *= 1.0-exp(3960.0/v*log(1.0-eff/100.0));
%}
COMPONENT image_plate_eff = COPY(image_plate_ideal)
AT (0,0,.1+1e-3) RELATIVE detector_axis
COMPONENT image_plate_scattered = COPY(image_plate_ideal)
WHEN(sample_scattered)
AT (0,0,.1+1e-3) RELATIVE detector_axis

This seems to have been recognized previously, as some example instruments work around the problem by defining identical EXTEND blocks on copied component instances, e.g.,

COMPONENT Cryo_1 = PowderN(reflections="Al.laz",
radius = 0.061, thickness = 0.001, yheight = 0.10,
concentric = 1, d_phi=RAD2DEG*atan(R_h/L3),
p_inc=Inc_Cryo, p_transmit=Trans_Cryo)
AT (0,0,L2) RELATIVE mono_out
EXTEND
%{
flag_env+=SCATTERED;
%}
COMPONENT Cryo_2 = COPY(Cryo_1)(radius = 0.0545, thickness = 0.001)
AT (0,0,L2) RELATIVE mono_out
EXTEND
%{
flag_env+=SCATTERED;
%}
COMPONENT Cryo_3 = COPY(Cryo_1)(radius = 0.039, thickness = 0.001)
AT (0,0,L2) RELATIVE mono_out
EXTEND
%{
flag_env+=SCATTERED;
%}
COMPONENT Cryo_4 = COPY(Cryo_1)(radius = 0.036, thickness = 0.001)
AT (0,0,L2) RELATIVE mono_out
EXTEND
%{
flag_env+=SCATTERED;
%}

From the warning messages, the problem seems to arise from the line number check in

McCode/mccode/src/instrument.y

Lines 1419 to 1443 in 03e2db0

if ($13->linenum) {
#ifdef GENERATE_C
if (comp->extend->linenum>0) {
fprintf(stderr, "\n-----------------------------------------------------------\n");
fprintf(stderr, "WARNING: Existing (COPY) EXTEND block in COMPONENT %s:\n", comp->name);
List_handle liter = list_iterate(comp->extend->lines);
List_handle liter2 = list_iterate($13->lines);
char *line, *line2;
fprintf(stderr, " EXTEND %%{\n");
while((line = list_next(liter))) {
fprintf(stderr, " %s",line);
}
list_iterate_end(liter);
fprintf(stderr, " %%}\n");
fprintf(stderr, "\nis overwritten by:\n");
fprintf(stderr, " EXTEND %%{\n");
while((line2 = list_next(liter2))) {
fprintf(stderr, " %s",line2);
}
list_iterate_end(liter2);
fprintf(stderr, " %%}\n-----------------------------------------------------------\n");
}
#endif
comp->extend= $13; /* EXTEND block*/
}

but the actual 'empty code block' initializer sets that to -1
struct code_block *
codeblock_new(void)
{
struct code_block *cb;
palloc(cb);
cb->filename = NULL;
cb->quoted_filename = NULL;
cb->linenum = -1;
cb->lines = list_create();
return cb;
}

so if ($13->linenum) is always true (unless if something else sets that to zero somewhere).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions