source: PSPA/madxPSPA/src/mad_seq.c @ 430

Last change on this file since 430 was 430, checked in by touze, 11 years ago

import madx-5.01.00

File size: 56.8 KB
Line 
1#include "madx.h"
2
3static void
4make_sequ_node(struct sequence* sequ, int occ_cnt)
5  /* makes + links a node pointing to a sub-sequence */
6{
7  prev_node = current_node;
8  current_node = new_sequ_node(sequ, occ_cnt);
9  current_node->occ_cnt = occ_cnt;
10  add_to_node_list(current_node, 0, current_sequ->nodes);
11  prev_node->next = current_node;
12  current_node->previous = prev_node;
13  current_node->next = NULL;
14}
15
16static struct sequence_list*
17delete_sequence_list(struct sequence_list* sql)
18{
19  char rout_name[] = "delete_sequence_list";
20  if (sql == NULL) return NULL;
21  if (stamp_flag && sql->stamp != 123456)
22    fprintf(stamp_file, "d_s_l double delete --> %s\n", sql->name);
23  if (watch_flag) fprintf(debug_file, "deleting --> %s\n", sql->name);
24  if (sql->list != NULL) delete_name_list(sql->list);
25  if (sql->sequs != NULL) myfree(rout_name, sql->sequs);
26  myfree(rout_name, sql);
27  return NULL;
28}
29
30static void
31dump_exp_sequ(struct sequence* sequ, int level)
32  /* executes the command dumpsequ, ... */
33{
34  struct node* c_node;
35  int j;
36  double suml = zero;
37  puts("+++++++++ dump expanded sequence +++++++++");
38  c_node = sequ->ex_start;
39  while(c_node != NULL)
40  {
41    suml += c_node->length;
42    if (level > 2)
43    {
44      dump_node(c_node);
45      if (c_node->p_al_err != NULL)
46      {
47        puts("alignment errors:");
48        for (j = 0; j < c_node->p_al_err->curr; j++)
49          printf(v_format("%F "), c_node->p_al_err->a[j]);
50        printf("\n");
51      }
52      if (c_node->p_fd_err != NULL)
53      {
54        puts("field errors:");
55        for (j = 0; j < c_node->p_fd_err->curr; j++)
56          printf(v_format("%e "), c_node->p_fd_err->a[j]);
57        printf("\n");
58      }
59      if (level > 3 && c_node->p_elem != NULL)  dump_element(c_node->p_elem);
60    }
61    else if (level > 0 && strcmp(c_node->base_name, "drift") != 0)
62      fprintf(prt_file, v_format("%S: at = %F  flag = %I\n"), c_node->name,
63              c_node->position, c_node->enable);
64    if (c_node == sequ->ex_end)  break;
65    c_node = c_node->next;
66  }
67  fprintf(prt_file, v_format("=== sum of node length: %F\n"), suml);
68}
69
70#if 0 // not used...
71static void
72dump_sequ(struct sequence* c_sequ, int level)
73{
74  struct node* c_node;
75  double suml = zero;
76  fprintf(prt_file, v_format("+++ dump sequence: %S\n"), c_sequ->name);
77  c_node = c_sequ->start;
78  while(c_node != NULL)
79  {
80    suml += c_node->length;
81    if (level > 2)
82    {
83      dump_node(c_node);
84      if (level > 3 && c_node->p_elem != NULL)  dump_element(c_node->p_elem);
85    }
86    else if (level > 0 && strcmp(c_node->base_name, "drift") != 0)
87      fprintf(prt_file, v_format("%S: at = %F\n"),
88              c_node->name, c_node->position);
89    if (c_node == c_sequ->end)  break;
90    c_node = c_node->next;
91  }
92  fprintf(prt_file, v_format("=== sum of node length: %F\n"), suml);
93}
94#endif
95
96static void
97grow_sequence_list(struct sequence_list* l)
98{
99  char rout_name[] = "grow_sequence_list";
100  struct sequence** sloc = l->sequs;
101  int j, new = 2*l->max;
102  l->max = new;
103  l->sequs
104    = (struct sequence**) mycalloc(rout_name,new, sizeof(struct sequence*));
105  for (j = 0; j < l->curr; j++) l->sequs[j] = sloc[j];
106  myfree(rout_name, sloc);
107}
108
109static void
110make_occ_list(struct sequence* sequ)
111  /* makes the node occurrence list */
112{
113  struct node* c_node = sequ->start;
114  int i;
115  while (c_node != NULL)
116  {
117    if (c_node->p_elem != NULL)
118    {
119      if ((i = name_list_pos(c_node->p_elem->name, occ_list)) < 0)
120        i = add_to_name_list(c_node->p_elem->name, 1, occ_list);
121      else ++occ_list->inform[i];
122    }
123    if (c_node == sequ->end) break;
124    c_node = c_node->next;
125  }
126}
127
128static void
129all_node_pos(struct sequence* sequ)
130  /* calculates all node positions in an expanded sequence */
131{
132  struct node* node = sequ->start;
133  while (node != NULL)
134  {
135    if (node->p_elem != NULL)
136      node->length = node->p_elem->length
137        = element_value(node, "l");
138    else if (node->p_sequ != NULL)
139      node->length = sequence_length(node->p_sequ);
140    else fatal_error("node is neither element nor sequence:",
141                     node->name);
142    if ((node->position = get_node_pos(node, sequ)) < zero)
143      node->position += sequence_length(sequ);
144    if (node == sequ->end) break;
145    node = node->next;
146  }
147}
148
149static struct sequence*
150extract_sequence(char* name, struct sequence* sequ, struct node* from, struct node* to, char* refpos)
151{
152  struct element* el;
153  int pos, marker_pos, from_cond;
154  struct command* clone;
155  struct sequence* keep_curr_sequ = current_sequ;
156  struct sequence* new_sequ;
157  struct node *q = from, *from_node;
158  struct node_list* new_nodes;
159  double start_value, end_value;
160  char tmp_name[2*NAME_L];
161
162  if (get_option("info")) printf("+++ extracting sequence %s from %s to %s\n",
163                                 sequ->name, from->name, to->name);
164  current_sequ = new_sequence(name, sequ->ref_flag);
165  current_sequ->share = 1; /* make shared for recombination */
166  current_sequ->refpos = refpos;
167  current_sequ->cavities = new_el_list(100);
168  new_nodes = new_node_list(1000);
169/* fill new_node list for 'from' references */
170  while (q)
171  {
172    add_to_node_list(q, 0, new_nodes);
173    if (q == to)  break;
174    q = q->next;
175  }
176/* sequence construction */
177  q = from;
178  start_value = get_node_pos(from, sequ);
179  end_value = get_node_pos(to, sequ);
180  current_sequ->l_expr = NULL;
181  current_sequ->length = end_value - start_value;
182  if (current_sequ->length < zero) current_sequ->length += sequ->length;
183  marker_pos = name_list_pos("marker", defined_commands->list);
184  clone = clone_command(defined_commands->commands[marker_pos]);
185  sprintf(c_dum->c, "%s$start", name);
186  el = make_element(c_dum->c, "marker", clone, 0);
187  current_node = NULL;
188  make_elem_node(el, 1);
189  current_sequ->start = current_node;
190  make_elem_node(from->p_elem, from->occ_cnt);
191  current_node->at_value = 0;
192  current_node->at_expr = NULL;
193/* loop over sequ nodes from 'from' to 'to' */
194  while (current_node != NULL)
195  {
196    while (strchr(q->next->name, '$')) q = q->next; /* suppress internal markers */
197    if (q->next->p_elem)
198      make_elem_node(q->next->p_elem, q->next->occ_cnt);
199    else if(q->next->p_sequ)
200      make_sequ_node(q->next->p_sequ, q->next->occ_cnt);
201    else
202      fatal_error("node has neither element nor sequence reference:", q->next->name);
203    q = q->next;
204    if (q->p_elem && strcmp(q->p_elem->base_type->name, "rfcavity") == 0 &&
205        find_element(q->p_elem->name, current_sequ->cavities) == NULL)
206      add_to_el_list(&q->p_elem, 0, current_sequ->cavities, 0);
207    from_cond = 0;
208    if (q->from_name)
209    {
210      strcpy(tmp_name, q->from_name);
211      strcat(tmp_name, ":1");
212      if ((pos = name_list_pos(tmp_name, sequ->nodes->list)) > -1)
213      {
214        from_node = sequ->nodes->nodes[pos];
215        from_cond = 1;
216        if (name_list_pos(tmp_name, new_nodes->list) > -1)
217          from_cond = 2;
218      }
219    }
220    if (from_cond == 2)
221    {
222      current_node->from_name = q->from_name;
223      current_node->at_value = q->at_value;
224      current_node->at_expr = q->at_expr;
225    }
226    else
227    {
228      if (from_cond == 1)
229        current_node->at_value = expr_combine(q->at_expr, q->at_value, " + ",
230                                              from_node->at_expr, from_node->at_value,
231                                              &current_node->at_expr);
232      else
233      {
234        current_node->at_expr = q->at_expr;
235        current_node->at_value = q->at_value;
236      }
237      current_node->at_value = expr_combine(current_node->at_expr,
238                                            current_node->at_value, " - ",
239                                            NULL, start_value,
240                                            &current_node->at_expr);
241      if (current_node->at_value < zero)
242        current_node->at_value = expr_combine(current_node->at_expr,
243                                              current_node->at_value, " + ",
244                                              sequ->l_expr, sequ->length,
245                                              &current_node->at_expr);
246    }
247    if (q == to) break;
248  }
249  clone = clone_command(defined_commands->commands[marker_pos]);
250  sprintf(c_dum->c, "%s$end", name);
251  el = make_element(c_dum->c, "marker", clone, 0);
252  make_elem_node(el, 1);
253  current_node->at_expr = current_sequ->l_expr;
254  current_node->at_value = current_sequ->length;
255  current_sequ->end = current_node;
256  current_node->next = current_sequ->start;
257  current_sequ->start->previous = current_node;
258  new_sequ = current_sequ;
259  current_sequ = keep_curr_sequ;
260  if (get_option("info"))
261    printf("+++ new sequence: %s  with current length = %.12g\n\n",
262           new_sequ->name, new_sequ->length);
263  return new_sequ;
264}
265
266static void
267fill_sequ_var_list(struct sequence_list* sql, struct el_list* ell, struct var_list* varl)
268  /* puts all variables a sequence depends on, in a list */
269{
270  int i;
271  struct sequence* sequ;
272  struct node* c_node;
273  for (i = 0; i < sql->curr; i++)
274  {
275    sequ = sql->sequs[i];
276    if (sequ->l_expr != NULL) fill_expr_var_list(ell, sequ->l_expr, varl);
277    c_node = sequ->start;
278    while(c_node != NULL)
279    {
280      if (c_node->at_expr != NULL)
281        fill_expr_var_list(ell, c_node->at_expr, varl);
282      if (c_node == sequ->end)  break;
283      c_node = c_node->next;
284    }
285  }
286}
287
288static void 
289seq_edit_ex(struct sequence* seq)
290{
291  edit_sequ = seq;
292  edit_is_on = 1;
293  seqedit_install = seqedit_move = seqedit_remove = 0;
294  if (edit_sequ->ex_start != NULL)
295  {
296    edit_sequ->ex_nodes = delete_node_list(edit_sequ->ex_nodes);
297    edit_sequ->ex_start = delete_node_ring(edit_sequ->ex_start);
298  }
299  if (occ_list == NULL)
300    occ_list = new_name_list("occ_list", 10000);  /* for occurrence count */
301  else occ_list->curr = 0;
302  resequence_nodes(edit_sequ);
303  all_node_pos(edit_sequ);
304}
305
306static void
307seq_end_ex(void)
308{
309  occ_list->curr = 0;
310  resequence_nodes(edit_sequ);
311  selected_ranges->curr = 0;
312  selected_ranges->list->curr = 0;
313  edit_is_on = 0;
314}
315
316static void
317expand_sequence(struct sequence* sequ, int flag)
318  /* expands a sequence into nodes, expands sequence nodes */
319{
320  /* Transfers errors from original nodes if flag != 0;
321     this is needed for SXF input  */
322  struct node *p, *q = sequ->start;
323  p = sequ->ex_start = clone_node(sequ->start, 0);
324  add_to_node_list(p, 0, sequ->ex_nodes);
325  while (p != NULL) {
326    if (q == sequ->end) break;
327    p->next = clone_node(q->next, flag);
328    p->next->previous = p;
329    p = p->next;
330    q = q->next;
331    if (p->p_sequ != NULL) p = expand_node(p, sequ, sequ, p->position);
332    else add_to_node_list(p, 0, sequ->ex_nodes);
333  }
334  sequ->ex_end = p;
335  sequ->ex_end->next = sequ->ex_start;
336  sequ->ex_start->previous = sequ->ex_end;
337  p = sequ->ex_start;
338  while (p != sequ->ex_end) {
339    if (strstr(p->base_name, "kicker") || strstr(p->base_name, "monitor"))
340      p->enable = 1; /* flag for orbit correction module */
341    p = p->next;
342  }
343
344  /*
345    Attempt to discard attached twiss table not anymore valid...
346    note: it cannot be done properly as table_register keep references
347          on-pointer-to-table (address of address) not to-table itself...
348          hence
349          if (sequ->tw_table) sequ->tw_table = NULL;
350          breaks the list of table_register used everywhere,
351          leading to bus error in many places (pointers are almost never checked)
352  */
353}
354
355static void
356seq_flatten(struct sequence* sequ)
357  /* executes flatten command */
358{
359  struct node* c_node;
360  struct node_list* nl;
361  if (occ_list == NULL)
362    occ_list = new_name_list("occ_list", 10000);  /* for occurrence count */
363  else occ_list->curr = 0;
364  make_occ_list(sequ);
365  all_node_pos(sequ);
366  sequ->ex_nodes = new_node_list(2*sequ->nodes->curr);
367  expand_sequence(sequ, 0);
368  sequ->nested = 0;
369  nl = sequ->nodes;
370  sequ->nodes = sequ->ex_nodes;
371  sequ->ex_nodes = delete_node_list(nl);
372  sequ->start = sequ->ex_start; sequ->ex_start = NULL;
373  sequ->end = sequ->ex_end; sequ->ex_end = NULL;
374  c_node = sequ->start;
375  while (c_node != NULL)
376  {
377    c_node->at_value = c_node->position;
378    c_node->at_expr = NULL;
379    c_node->from_name = NULL;
380    if (c_node == sequ->end) break;
381    c_node = c_node->next;
382  }
383  sequ->ref_flag = 0;
384}
385
386static void
387insert_elem(struct sequence* sequ, struct node* node)
388  /* inserts an element in a sequence as function of its position */
389{
390  struct node* c_node = sequ->start->next;
391
392  while (c_node != NULL)
393  {
394    if (node->position <= c_node->position || c_node == sequ->end) break;
395    c_node = c_node->next;
396  }
397  link_in_front(node, c_node);
398}
399
400static struct node*
401install_one(struct element* el, char* from_name, double at_value, struct expression* at_expr, double position)
402  /* adds an element to a sequence */
403{
404  struct node* node;
405  int i, occ = 1;
406  if (strcmp(el->base_type->name, "rfcavity") == 0 &&
407      find_element(el->name, edit_sequ->cavities) == NULL)
408    add_to_el_list(&el, 0, edit_sequ->cavities, 0);
409  if ((i = name_list_pos(el->name, occ_list)) < 0)
410    i = add_to_name_list(el->name, occ, occ_list);
411  else occ = ++occ_list->inform[i];
412  node = new_elem_node(el, occ);
413  add_to_node_list(node, 0, edit_sequ->nodes);
414  node->position = position;
415  node->at_value = at_value;
416  node->at_expr = at_expr;
417  node->from_name = from_name;
418  set_command_par_value("at", el->def, position);
419  insert_elem(edit_sequ, node);
420  return node;
421}
422
423static void
424make_sequ_from_line(char* name)
425  /* converts a line into a sequence from actual line definition */
426{
427  char** tmp = NULL;
428  int pos = name_list_pos(name, line_list->list);
429  int spos;
430  struct sequence* old_sequ = NULL;
431  struct macro* line;
432  int mpos = name_list_pos("marker", defined_commands->list);
433  struct command* clone = clone_command(defined_commands->commands[mpos]);
434  struct element* el;
435  if (pos < 0) fatal_error("unknown line: ", name);
436  line = line_list->macros[pos];
437  line->dead = 1;   /* prevent line from further conversion to sequence */
438  line_buffer = new_char_p_array(1000);
439  replace_lines(line, 0, tmp); /* replaces all referenced lines */
440  expand_line(line_buffer); /* act on '-' and rep. count */
441  current_sequ = new_sequence(name, 0); /* node positions = centre */
442  if ((spos = name_list_pos(name, sequences->list)) >= 0)
443    old_sequ = sequences->sequs[spos];
444  add_to_sequ_list(current_sequ, sequences);
445  if (old_sequ) old_sequ = delete_sequence(old_sequ);
446  if (current_sequ->cavities != NULL)  current_sequ->cavities->curr = 0;
447  else current_sequ->cavities = new_el_list(100);
448  if (occ_list == NULL)
449    occ_list = new_name_list("occ_list", 10000);  /* for occurrence count */
450  else occ_list->curr = 0;
451  sprintf(c_dum->c, "%s$start", current_sequ->name);
452  el = make_element(c_dum->c, "marker", clone, 0);
453  current_node = NULL;
454  make_elem_node(el, 1);
455  current_sequ->start = current_node;
456  current_sequ->length = line_nodes(line_buffer);
457  sprintf(c_dum->c, "%s$end", current_sequ->name);
458  el = make_element(c_dum->c, "marker", clone, 0);
459  make_elem_node(el, 1);
460  current_node->at_value = current_node->position = current_sequ->length;
461  current_sequ->end = current_node;
462  current_sequ->start->previous = current_sequ->end;
463  current_sequ->end->next = current_sequ->start;
464  current_sequ->line = 1; /* remember origin of sequence */
465  if(line_buffer) delete_char_p_array(line_buffer,1);
466}
467
468static void
469export_sequence(struct sequence* sequ, FILE* file)
470  /* exports sequence in mad-X format */
471{
472  char num[2*NAME_L];
473  struct element* el;
474  struct sequence* sq;
475  struct node* c_node = sequ->start;
476  int exp_par_flag;
477  int seqref = 0;
478  char rpos[3][6] = {"exit", "centre", "entry"};
479  seqref = sequ->ref_flag;  /* uncomment line to get entry or exit */
480  *c_dum->c = '\0';
481  if (sequ->share) strcat(c_dum->c, "shared ");
482  strcat(c_dum->c, sequ->export_name);
483  strcat(c_dum->c, ": sequence");
484  if (seqref)
485  {
486    strcat(c_dum->c, ", refer = ");
487    strcat(c_dum->c, rpos[seqref+1]);
488  }
489  if (sequ->refpos != NULL)
490  {
491    strcat(c_dum->c, ", refpos = ");
492    strcat(c_dum->c, sequ->refpos);
493  }
494  strcat(c_dum->c, ", l = ");
495  if (sequ->l_expr != NULL) strcat(c_dum->c, sequ->l_expr->string);
496  else
497  {
498    sprintf(num, v_format("%F"), sequence_length(sequ));
499    strcat(c_dum->c, supp_tb(num));
500  }
501  write_nice(c_dum->c, file);
502  while(c_node != NULL)
503  {
504    exp_par_flag = 0;
505    *c_dum->c = '\0';
506    if (strchr(c_node->name, '$') == NULL
507        && strstr(c_node->name, "_p_") == NULL
508        && strcmp(c_node->base_name, "drift") != 0)
509    {
510      if ((el = c_node->p_elem) != NULL)
511      {
512        if (c_node->p_elem->def_type)
513        {
514          strcat(c_dum->c, el->name);
515          strcat(c_dum->c, ": ");
516          strcat(c_dum->c, el->parent->name);
517          exp_par_flag = 1;
518        }
519        else strcat(c_dum->c, el->name);
520      }
521      else if ((sq = c_node->p_sequ) != NULL) strcat(c_dum->c, sq->name);
522      else fatal_error("save error: node without link:", c_node->name);
523      strcat(c_dum->c, ", at = ");
524      if (c_node->at_expr != NULL) strcat(c_dum->c, c_node->at_expr->string);
525      else
526      {
527        sprintf(num, v_format("%F"), c_node->at_value);
528        strcat(c_dum->c, supp_tb(num));
529      }
530      if (c_node->from_name != NULL)
531      {
532        strcat(c_dum->c, ", from = ");
533        strcat(c_dum->c, c_node->from_name);
534      }
535      if (exp_par_flag) export_el_def(c_node->p_elem, c_dum->c);
536      write_nice(c_dum->c, file);
537    }
538    if (c_node == sequ->end)  break;
539    c_node = c_node->next;
540  }
541  strcpy(c_dum->c, "endsequence");
542  write_nice(c_dum->c, file);
543}
544
545static void
546export_sequ_8(struct sequence* sequ, struct command_list* cl, FILE* file)
547  /* exports sequence in mad-8 format */
548  /* set refer = centre always (local var. seqref) HG 9.1.09 */
549{
550  char num[2*NAME_L];
551  int exp_par_flag;
552  int seqref = 0;
553  struct element* el;
554  struct sequence* sq;
555  struct node* c_node = sequ->start;
556  seqref = sequ->ref_flag;  /* uncomment line to get entry or exit */
557  if (pass_select_list(sequ->name, cl) == 0)  return;
558  *c_dum->c = '\0';
559  strcat(c_dum->c, sequ->export_name);
560  strcat(c_dum->c, ": sequence");
561  if (seqref ==1)  strcat(c_dum->c, ", refer=entry");
562  write_nice_8(c_dum->c, file);
563  while(c_node != NULL)
564  {
565    exp_par_flag = 0;
566    *c_dum->c = '\0';
567    if (strchr(c_node->name, '$') == NULL
568        && strcmp(c_node->base_name, "drift") != 0)
569    {
570      if ((el = c_node->p_elem) != NULL)
571      {
572        if (c_node->p_elem->def_type)
573        {
574          strcat(c_dum->c, el->name);
575          strcat(c_dum->c, ": ");
576          strcat(c_dum->c, el->parent->name);
577          exp_par_flag = 1;
578        }
579        else strcat(c_dum->c, el->name);
580      }
581      else if ((sq = c_node->p_sequ) != NULL) strcat(c_dum->c, sq->name);
582      else fatal_error("save error: node without link:", c_node->name);
583      strcat(c_dum->c, ", at = ");
584      if (c_node->at_expr != NULL) strcat(c_dum->c, c_node->at_expr->string);
585      else
586      {
587        sprintf(num, v_format("%F"), c_node->at_value);
588        strcat(c_dum->c, supp_tb(num));
589      }
590      if (c_node->from_name != NULL)
591      {
592        strcat(c_dum->c, ", from = ");
593        strcat(c_dum->c, c_node->from_name);
594      }
595      if (exp_par_flag)  export_el_def_8(c_node->p_elem, c_dum->c);
596      write_nice_8(c_dum->c, file);
597    }
598    if (c_node == sequ->end)  break;
599    c_node = c_node->next;
600  }
601  strcpy(c_dum->c, sequ->name);
602  strcat(c_dum->c, "_end: marker, at = ");
603  sprintf(num, v_format("%F"), sequence_length(sequ));
604  strcat(c_dum->c,num);
605  write_nice_8(c_dum->c, file);
606  strcpy(c_dum->c, "endsequence");
607  write_nice_8(c_dum->c, file);
608}
609
610static void
611write_sequs(struct sequence_list* sql,struct command_list* cl, FILE* file)
612{
613  /* exports sequences in order of their nest level, flat first etc. */
614  int i, j, max_nest = 0;
615  for (i = 0; i < sql->curr; i++)
616    if(sql->sequs[i]->nested > max_nest) max_nest = sql->sequs[i]->nested;
617  for (j = 0; j <= max_nest; j++)
618  {
619    for (i = 0; i < sql->curr; i++)
620      if(sql->sequs[i]->nested == j)
621      {
622        if (pass_select_list(sql->sequs[i]->name, cl))
623          export_sequence(sql->sequs[i], file);
624      }
625  }
626}
627
628static void
629seq_cycle(struct in_cmd* cmd)
630  /* cycles a sequence */
631{
632  struct name_list* nl = cmd->clone->par_names;
633  struct command_parameter_list* pl = cmd->clone->par;
634  struct node *node, *clone;
635  char* name = NULL;
636  int pos = name_list_pos("start", nl);
637  if (nl->inform[pos] && (name = pl->parameters[pos]->string) != NULL)
638  {
639    sprintf(c_dum->c, "%s:1", name);
640    if ((pos = name_list_pos(c_dum->c, edit_sequ->nodes->list)) > -1)
641    {
642      node = edit_sequ->nodes->nodes[pos];
643      sprintf(c_dum->c, "%s%s_p_", edit_sequ->name,strip(node->name));
644      if (strstr(node->previous->name, "_p_") == NULL)
645      {
646        clone = clone_node(node, 0);
647        clone->p_elem = clone_element(node->p_elem);
648        strcpy(clone->p_elem->name, c_dum->c);
649
650        /* IA 29.11.07 : fixes a bug with aperture module */
651/* Removed HG 11.10.2009 */
652        /* sprintf(c_dum->c, " ");
653           set_command_par_string("apertype", clone->p_elem->def,c_dum->c); */
654
655
656        add_to_el_list(&clone->p_elem, node->p_elem->def->mad8_type,
657                       element_list, 1);
658        link_in_front(clone, node);
659      }
660      edit_sequ->start = node;
661      edit_sequ->end = node->previous;
662      set_new_position(edit_sequ);
663      all_node_pos(edit_sequ);
664    }
665    else warning("cycle: unknown element ignored:", name);
666  }
667  else warning("cycle: no start given,","ignored");
668}
669
670static void
671seq_edit(struct in_cmd* cmd)
672  /* executes seqedit command */
673{
674  struct name_list* nl = cmd->clone->par_names;
675  struct command_parameter_list* pl = cmd->clone->par;
676  char* name = NULL;
677  int pos;
678  pos = name_list_pos("sequence", nl);
679  if (nl->inform[pos] && (name = pl->parameters[pos]->string) != NULL)
680  {
681    if ((pos = name_list_pos(name, sequences->list)) >= 0)
682    {
683      if (sequences->sequs[pos]->line)
684        warning("sequence originates from line,","edit ignored");
685      else  seq_edit_ex(sequences->sequs[pos]);
686    }
687    else warning("unknown sequence:", "ignored");
688  }
689  else warning("seqedit without sequence:", "ignored");
690}
691
692static void
693seq_end(struct in_cmd* cmd)
694  /* executes endedit command */
695{
696  char tmp[8];
697  (void)cmd;
698  sprintf(tmp, "%d", seqedit_install);
699  put_info("seqedit - number of elements installed: ", tmp);
700  sprintf(tmp, "%d", seqedit_move);
701  put_info("seqedit - number of elements moved:     ", tmp);
702  sprintf(tmp, "%d", seqedit_remove);
703  put_info("seqedit - number of elements removed:   ", tmp);
704  seq_end_ex();
705}
706
707static void
708seq_install(struct in_cmd* cmd)
709  /* executes install command */
710{
711  struct name_list* nl = cmd->clone->par_names;
712  struct command_parameter_list* pl = cmd->clone->par;
713  struct element *cl, *el;
714  struct node* c_node;
715  struct expression* expr = NULL;
716  double at, from = zero;
717  char name[NAME_L], *pname, *name_e = NULL, *name_c = NULL, *from_name = NULL;
718  int k, pos, any = 0;
719  int pos_e = name_list_pos("element", nl);
720  int pos_c = name_list_pos("class", nl);
721  if (nl->inform[pos_e] && (name_e = pl->parameters[pos_e]->string) != NULL)
722  {
723    if (nl->inform[pos_c] && (name_c = pl->parameters[pos_c]->string) != NULL)
724    {
725      if ((cl = find_element(name_c, element_list)) == NULL)
726      {
727        warning("ignored because of unknown class:", name_c);
728        return;
729      }
730      else
731      {
732        el = clone_element(cl);
733        strcpy(el->name, name_e);
734        add_to_el_list(&el, cl->def->mad8_type, element_list, 2);
735      }
736    }
737    else if ((el = find_element(name_e, element_list)) == NULL)
738    {
739      warning("ignored, unknown command or element:", name_c); return;
740    }
741  }
742  else
743  {
744    warning("no element specified,","ignored"); return;
745  }
746  if (nl->inform[name_list_pos("at", nl)] == 0)
747  {
748    warning("no 'at':", "ignored"); return;
749  }
750  at = command_par_value("at", cmd->clone);
751  expr = clone_expression(command_par_expr("at", cmd->clone));
752  pos = name_list_pos("from", nl);
753  if (nl->inform[pos])
754  {
755    from_name = pl->parameters[pos]->string;
756    if (strcmp(from_name, "selected") == 0)
757    {
758      if (seqedit_select->curr == 0)
759      {
760        warning("no active select commands:", "ignored"); return;
761      }
762      else
763      {
764        if (get_select_ranges(edit_sequ, seqedit_select, selected_ranges)
765            == 0) any = 1;
766        c_node = edit_sequ->start;
767        while (c_node != NULL)
768        {
769          if (any
770              || name_list_pos(c_node->name, selected_ranges->list) > -1)
771          {
772            for (k = 0; k < seqedit_select->curr; k++)
773            {
774              myrepl(":", "[", c_node->name, name);
775              strcat(name, "]");
776              if (strchr(name, '$') == NULL &&
777                  pass_select(c_node->name,
778                              seqedit_select->commands[k])) break;
779            }
780            if (k < seqedit_select->curr)
781            {
782              from = get_node_pos(c_node, edit_sequ);
783              pname = permbuff(name);
784              install_one(el, pname, at, expr, at+from);
785              seqedit_install++;
786            }
787          }
788          if (c_node == edit_sequ->end) break;
789          c_node = c_node->next;
790        }
791      }
792    }
793    else
794    {
795      from_name = permbuff(pl->parameters[pos]->string);
796      if ((from = hidden_node_pos(from_name, edit_sequ)) == INVALID)
797      {
798        warning("ignoring 'from' reference to unknown element:", from_name);
799        return;
800      }
801      install_one(el, from_name, at, expr, at+from);
802      seqedit_install++;
803    }
804  }
805  else
806  {
807    install_one(el, from_name, at, expr, at);
808    seqedit_install++;
809  }
810}
811
812static void
813seq_move(struct in_cmd* cmd)
814  /* executes move command */
815{
816  char *name, *from_name;
817  double at, by, to, from = zero;
818  int any = 0, k;
819  struct node *node, *next;
820  struct element* el;
821  struct name_list* nl = cmd->clone->par_names;
822  struct command_parameter_list* pl = cmd->clone->par;
823  int pos = name_list_pos("element", nl);
824  if (nl->inform[pos] && (name = pl->parameters[pos]->string) != NULL)
825  {
826    if (strcmp(name, "selected") == 0)
827    {
828      if (seqedit_select->curr == 0)
829      {
830        warning("no active select commands:", "ignored"); return;
831      }
832      else
833      {
834        if (nl->inform[name_list_pos("by", nl)] == 0)
835        {
836          warning("no 'by' given,", "ignored"); return;
837        }
838        by = command_par_value("by", cmd->clone);
839        if (get_select_ranges(edit_sequ, seqedit_select, selected_ranges)
840            == 0) any = 1;
841        node = edit_sequ->start;
842        while (node != edit_sequ->end)
843        {
844          node = node->next; node->moved = 0;
845        }
846        node = edit_sequ->start;
847        while (node != NULL && node != edit_sequ->end)
848        {
849          next = node->next;
850          if (node->moved == 0)
851          {
852            if (any
853                || name_list_pos(node->name, selected_ranges->list) > -1)
854            {
855              name = NULL;
856              for (k = 0; k < seqedit_select->curr; k++)
857              {
858                if (node->p_elem != NULL) name = node->p_elem->name;
859                if (name != NULL && strchr(name, '$') == NULL &&
860                    pass_select(name,
861                                seqedit_select->commands[k])) break;
862              }
863              if (k < seqedit_select->curr)
864              {
865                at = node->position + by;
866                el = node->p_elem;
867                if (remove_one(node) > 0)
868                {
869                  node = install_one(el, NULL, at, NULL, at);
870                  node->moved = 1;
871                  seqedit_move++;
872                }
873              }
874            }
875          }
876          node = next;
877        }
878      }
879    }
880    else
881    {
882      strcpy(c_dum->c, name);
883      square_to_colon(c_dum->c);
884      if ((pos = name_list_pos(c_dum->c, edit_sequ->nodes->list)) > -1)
885      {
886        node = edit_sequ->nodes->nodes[pos];
887        if (nl->inform[name_list_pos("by", nl)] == 0)
888        {
889          if (nl->inform[name_list_pos("to", nl)] == 0)
890          {
891            warning("no position given,", "ignored"); return;
892          }
893          to = command_par_value("to", cmd->clone);
894          pos = name_list_pos("from", nl);
895          if (nl->inform[pos])
896          {
897            from_name = pl->parameters[pos]->string;
898            if ((from = hidden_node_pos(from_name, edit_sequ)) == INVALID)
899            {
900              warning("ignoring 'from' reference to unknown element:",
901                      from_name);
902              return;
903            }
904          }
905          at = to + from;
906        }
907        else
908        {
909          by = command_par_value("by", cmd->clone);
910          at = node->position + by;
911        }
912        el = node->p_elem;
913        if (remove_one(node) > 0)
914        {
915          install_one(el, NULL, at, NULL, at);
916          seqedit_move++;
917        }
918      }
919    }
920  }
921}
922
923static void
924seq_reflect(struct in_cmd* cmd)
925  /* executes reflect command */
926{
927  struct node *tmp, *c_node;
928
929  (void)cmd;
930  c_node = edit_sequ->start;
931  while (c_node != NULL)
932  {
933    tmp = c_node->next;
934    c_node->next = c_node->previous;
935    c_node->previous = tmp;
936    if (c_node == edit_sequ->end) break;
937    c_node = tmp;
938  }
939  tmp = edit_sequ->start;
940  edit_sequ->start = edit_sequ->end;
941  edit_sequ->end = tmp;
942  c_node = edit_sequ->start;
943  edit_sequ->range_start = edit_sequ->start;
944  edit_sequ->range_end = edit_sequ->end;
945  while (c_node != NULL)
946  {
947    c_node->at_expr = NULL;
948    c_node->from_name = NULL;
949    c_node->position = c_node->at_value
950      = sequence_length(edit_sequ) - c_node->position;
951    if (c_node == edit_sequ->end) break;
952    c_node = c_node->next;
953  }
954}
955
956static void
957seq_remove(struct in_cmd* cmd)
958  /* executes remove command */
959{
960  struct name_list* nl = cmd->clone->par_names;
961  struct command_parameter_list* pl = cmd->clone->par;
962  struct node *c_node;
963  char *name;
964  int k, any = 0;
965  int pose = name_list_pos("element", nl);
966  if (nl->inform[pose] && (name = pl->parameters[pose]->string) != NULL)
967  {
968    if (strcmp(name, "selected") == 0)
969    {
970      if (seqedit_select->curr == 0)
971      {
972        warning("no active select commands:", "ignored"); return;
973      }
974      else
975      {
976        if (get_select_ranges(edit_sequ, seqedit_select, selected_ranges)
977            == 0) any = 1;
978        c_node = edit_sequ->start;
979        while (c_node != NULL)
980        {
981          if (any
982              || name_list_pos(c_node->name, selected_ranges->list) > -1)
983          {
984            name = NULL;
985            for (k = 0; k < seqedit_select->curr; k++)
986            {
987              if (c_node->p_elem != NULL) name = c_node->p_elem->name;
988              if (name != NULL && strchr(name, '$') == NULL &&
989                  pass_select(name,
990                              seqedit_select->commands[k])) break;
991            }
992            if (k < seqedit_select->curr)
993            {
994              seqedit_remove += remove_one(c_node);
995            }
996          }
997          if (c_node == edit_sequ->end) break;
998          c_node = c_node->next;
999        }
1000      }
1001    }
1002    else
1003    {
1004      strcpy(c_dum->c, name);
1005      square_to_colon(c_dum->c);
1006      if ((pose = name_list_pos(c_dum->c, edit_sequ->nodes->list)) > -1)
1007      {
1008        seqedit_remove += remove_one(edit_sequ->nodes->nodes[pose]);
1009      }
1010      else warning("ignored because of unknown element:", name);
1011    }
1012  }
1013  else  warning("no element specified,","ignored");
1014}
1015
1016static void
1017seq_replace(struct in_cmd* cmd)
1018  /* executes replace command */
1019{
1020  struct name_list* nl = cmd->clone->par_names;
1021  struct command_parameter_list* pl = cmd->clone->par;
1022  struct node** rep_nodes = NULL;
1023  struct element** rep_els = NULL;
1024  struct node *node, *c_node;
1025  char* name;
1026  struct element* el;
1027  int count = count_nodes(edit_sequ);
1028  int any = 0, k, rep_cnt = 0, pos = name_list_pos("element", nl);
1029  if (nl->inform[pos] && (name = pl->parameters[pos]->string) != NULL)
1030  {
1031    if (strcmp(name, "selected") == 0)
1032    {
1033      if (seqedit_select->curr == 0)
1034      {
1035        warning("no active select commands:", "ignored"); return;
1036      }
1037      else
1038      {
1039        pos = name_list_pos("by", nl);
1040        if (nl->inform[pos] && (name = pl->parameters[pos]->string) != NULL)
1041        {
1042          if ((el = find_element(name, element_list)) == NULL)
1043          {
1044            warning("ignoring unknown 'by' element:",name);
1045            return;
1046          }
1047        }
1048        else
1049        {
1050          warning("'by' missing, ","ignored");
1051          return;
1052        }
1053        rep_nodes = (struct node**)
1054          mymalloc("seq_replace", count*sizeof(struct node*));
1055        rep_els = (struct element**)
1056          mymalloc("seq_replace", count*sizeof(struct element*));
1057        if (get_select_ranges(edit_sequ, seqedit_select, selected_ranges)
1058            == 0) any = 1;
1059        c_node = edit_sequ->start;
1060        while (c_node != NULL)
1061        {
1062          if (any || name_list_pos(c_node->name, selected_ranges->list) > -1)
1063          {
1064            name = NULL;
1065            for (k = 0; k < seqedit_select->curr; k++)
1066            {
1067              if (c_node->p_elem != NULL) name = c_node->p_elem->name;
1068              if (name != NULL && strchr(name, '$') == NULL &&
1069                  pass_select(name,
1070                              seqedit_select->commands[k])) break;
1071            }
1072            if (k < seqedit_select->curr)
1073            {
1074              rep_els[rep_cnt] = el;
1075              rep_nodes[rep_cnt++] = c_node;
1076            }
1077          }
1078          if (c_node == edit_sequ->end) break;
1079          c_node = c_node->next;
1080        }
1081      }
1082    }
1083    else
1084    {
1085      rep_nodes = (struct node**)
1086        mymalloc("seq_replace", count*sizeof(struct node*));
1087      rep_els = (struct element**)
1088        mymalloc("seq_replace", count*sizeof(struct element*));
1089      strcpy(c_dum->c, name);
1090      square_to_colon(c_dum->c);
1091      if ((pos = name_list_pos(c_dum->c, edit_sequ->nodes->list)) > -1)
1092      {
1093        node = edit_sequ->nodes->nodes[pos];
1094        pos = name_list_pos("by", nl);
1095        if (nl->inform[pos] && (name = pl->parameters[pos]->string) != NULL)
1096        {
1097          if ((el = find_element(name, element_list)) != NULL)
1098          {
1099            rep_els[rep_cnt] = el;
1100            rep_nodes[rep_cnt++] = node;
1101          }
1102          else warning("ignoring unknown 'by' element: ",name);
1103        }
1104        else warning("'by' missing, ","ignored");
1105      }
1106      else warning("ignored because of unknown element: ", name);
1107    }
1108    for (k = 0; k < rep_cnt; k++)  replace_one(rep_nodes[k], rep_els[k]);
1109    if (rep_nodes) myfree("seq_replace", rep_nodes);
1110    if (rep_els)   myfree("seq_replace", rep_els);
1111  }
1112  else  warning("no element specified, ","ignored");
1113}
1114
1115#if 0 // not used...
1116static void
1117sequence_name(char* name, int* l)
1118  /* returns current sequence name in Fortran format */
1119{
1120  int sname_l = strlen(current_sequ->name);
1121  int i, ncp = sname_l < *l ? sname_l : *l;
1122  int nbl = *l - ncp;
1123  for (i = 0; i < ncp; i++) name[i] = current_sequ->name[i];
1124  for (i = 0; i < nbl; i++) name[ncp+i] = ' ';
1125}
1126#endif
1127
1128void
1129use_sequ(struct in_cmd* cmd)
1130{
1131  char rout_name[] = "use_sequ";
1132  struct name_list* nl = cmd->clone->par_names;
1133  struct command_parameter_list* pl = cmd->clone->par;
1134  struct command* keep_beam = current_beam;
1135  int pos, lp;
1136  char* name;
1137
1138  if (sequ_is_on)
1139    fatal_error("no endsequence yet for sequence:", current_sequ->name);
1140
1141  // YIL: calling use screws up any twiss table calculated.. this is a "quick fix"
1142  pos = name_list_pos("period", nl);
1143  if (nl->inform[pos] == 0) pos = name_list_pos("sequence", nl);
1144
1145  if (nl->inform[pos]) {  /* parameter has been read */
1146    if (current_range != NULL) {
1147      myfree(rout_name, current_range); current_range = NULL;
1148    }
1149
1150    name = pl->parameters[pos]->string;
1151    if ((pos = name_list_pos(name, line_list->list)) > -1 && line_list->macros[pos]->dead == 0)
1152      make_sequ_from_line(name); /* only if not disabled */
1153
1154    if ((lp = name_list_pos(name, sequences->list)) > -1) {
1155      current_sequ = sequences->sequs[lp];
1156
1157      if (attach_beam(current_sequ) == 0)
1158        fatal_error("USE - sequence without beam:", current_sequ->name);
1159
1160      current_sequ->beam = current_beam;
1161      pos = name_list_pos("range", nl);
1162      if (nl->inform[pos])  /* parameter has been read */
1163        current_range = tmpbuff(pl->parameters[pos]->string);
1164
1165      current_sequ->tw_valid = 0;
1166      expand_curr_sequ(0);
1167
1168      pos = name_list_pos("survey", nl);
1169      if (nl->inform[pos]) {  /* parameter has been read */
1170         pro_use_survey();
1171         pos = name_list_pos("survtest", nl);
1172         if (nl->inform[pos]) survtest_();
1173         exec_delete_table("survey");
1174        }
1175    }
1176    else warning("unknown sequence skipped:", name);
1177  }
1178
1179  current_beam = keep_beam;
1180}
1181
1182int
1183sequ_check_valid_twiss(struct sequence * sequ)
1184{
1185  return sequ->tw_table != NULL && sequ->tw_valid;
1186}
1187
1188int
1189set_cont_sequence(void)
1190{
1191  if (current_sequ->next_sequ != NULL)
1192    {
1193     set_sequence(current_sequ->next_sequ);
1194     return 1;
1195    }
1196  else return 0;
1197}
1198
1199void
1200set_sequence(char* name)
1201{
1202  int lp;
1203  struct sequence* t_sequ;
1204  mycpy(c_dum->c, name);
1205  /* makes sequence "name" the current sequence */
1206  if ((lp = name_list_pos(c_dum->c, sequences->list)) > -1)
1207    t_sequ = sequences->sequs[lp];
1208  else
1209  {
1210    warning("unknown sequence ignored:", name);
1211    return;
1212  }
1213  if (attach_beam(t_sequ) == 0)
1214    fatal_error("USE - sequence without beam:", t_sequ->name);
1215  t_sequ->beam = current_beam;
1216  if (t_sequ == NULL || t_sequ->ex_start == NULL)
1217  {
1218    warning("sequence not active,", "SET ignored");
1219    return;
1220  }
1221  current_sequ = t_sequ;
1222}
1223
1224// public interface
1225
1226struct sequence*
1227new_sequence(char* name, int ref)
1228{
1229  char rout_name[] = "new_sequence";
1230  struct sequence* s = mycalloc(rout_name,1, sizeof(struct sequence));
1231  strcpy(s->name, name);
1232  s->stamp = 123456;
1233  if (watch_flag) fprintf(debug_file, "creating ++> %s\n", s->name);
1234  s->ref_flag = ref;
1235  s->nodes = new_node_list(10000);
1236  return s;
1237}
1238
1239struct sequence_list*
1240new_sequence_list(int length)
1241{
1242  char rout_name[] = "new_sequence_list";
1243  struct sequence_list* s
1244    = mycalloc(rout_name,length, sizeof(struct sequence_list));
1245  strcpy(s->name, "sequence_list");
1246  s->stamp = 123456;
1247  if (watch_flag) fprintf(debug_file, "creating ++> %s\n", s->name);
1248  s->max = length;
1249  s->list = new_name_list(s->name, length);
1250  s->sequs
1251    = (struct sequence**) mycalloc(rout_name,length, sizeof(struct sequence*));
1252  return s;
1253}
1254
1255struct node*
1256new_sequ_node(struct sequence* sequ, int occ_cnt)
1257{
1258  struct node* p;
1259  p = new_node(compound(sequ->name, occ_cnt));
1260  p->p_sequ = sequ;
1261  p->length = sequence_length(sequ);
1262  p->base_name = permbuff("sequence");
1263  return p;
1264}
1265
1266struct sequence*
1267delete_sequence(struct sequence* sequ)
1268{
1269  char rout_name[] = "delete_sequence";
1270  int lp;
1271  if (sequ->ex_start != NULL)
1272  {
1273    sequ->ex_nodes = delete_node_list(sequ->ex_nodes);
1274    sequ->ex_start = delete_node_ring(sequ->ex_start);
1275    sequ->orbits = delete_vector_list(sequ->orbits);
1276    myfree(rout_name, sequ->all_nodes);
1277  }
1278  if ((lp = name_list_pos(sequ->name, sequences->list)) > -1)
1279    remove_from_sequ_list(sequences->sequs[lp], sequences);
1280  if (sequ->l_expr) sequ->l_expr = delete_expression(sequ->l_expr);
1281  sequ->nodes = delete_node_list(sequ->nodes);
1282  sequ->start = delete_node_ring(sequ->start);
1283  if (sequ->cavities) sequ->cavities = delete_el_list(sequ->cavities);
1284  myfree(rout_name, sequ);
1285  return NULL;
1286}
1287
1288void
1289remove_from_sequ_list(struct sequence* sequ, struct sequence_list* sql)
1290  /* removes sequence sequ from sequence list sql */
1291{
1292  int i;
1293  if ((i = remove_from_name_list(sequ->name, sql->list)) > -1)
1294    sql->sequs[i] = sql->sequs[--sql->curr];
1295  return;
1296}
1297
1298double
1299sequence_length(struct sequence* sequ)
1300{
1301  double val = 0;
1302  if (sequ)
1303  {
1304    if (sequ->l_expr) 
1305      val = sequ->length = expression_value(sequ->l_expr,2);
1306    else val = sequ->length;
1307  }
1308  return val;
1309}
1310
1311void
1312enter_sequence(struct in_cmd* cmd)
1313  /* handles sequence start and end on input */
1314{
1315  struct name_list* nl;
1316  struct command_parameter_list* pl;
1317  int i, k = 0, pos, aux_pos;
1318  char** toks = cmd->tok_list->p;
1319  struct element* el;
1320  struct command* clone;
1321  aux_pos = strcmp(toks[0], "shared") == 0 ? 1 : 0;
1322  if (strcmp(toks[0], "endsequence") == 0)
1323  {
1324    pos = name_list_pos("marker", defined_commands->list);
1325    clone = clone_command(defined_commands->commands[pos]);
1326    sprintf(c_dum->c, "%s$end", current_sequ->name);
1327    el = make_element(c_dum->c, "marker", clone, 0);
1328    make_elem_node(el, 1);
1329    current_node->at_expr = current_sequ->l_expr;
1330    current_node->at_value = current_sequ->length;
1331    current_sequ->end = current_node;
1332    current_sequ->start->previous = current_sequ->end;
1333    current_sequ->end->next = current_sequ->start;
1334  }
1335  else if (strcmp(toks[aux_pos+2], "sequence") == 0)
1336  {
1337    for (i = aux_pos+3; i < cmd->tok_list->curr; i++)
1338    {
1339      if (strcmp(toks[i], "refer") == 0)
1340      {
1341        if (i+2 < cmd->tok_list->curr)
1342        {
1343          if (strcmp(toks[i+2], "entry") == 0)  k = 1;
1344          else if (strcmp(toks[i+2], "exit") == 0)  k = -1;
1345        }
1346        break;
1347      }
1348    }
1349    if ((pos = name_list_pos(toks[aux_pos], sequences->list)) >= 0)
1350    {
1351      /*printf("enter_sequence: removing %s\n", sequences->sequs[pos]->name);*/
1352      remove_from_sequ_list(sequences->sequs[pos], sequences);
1353      sequences->sequs[pos] = delete_sequence(sequences->sequs[pos]);
1354    }
1355    current_sequ = new_sequence(toks[aux_pos], k);
1356    add_to_sequ_list(current_sequ, sequences);
1357    cmd->clone = clone_command(cmd->cmd_def);
1358/* prevent a line with this name from expansion */
1359    disable_line(current_sequ->name, line_list);
1360    scan_in_cmd(cmd);
1361    nl = cmd->clone->par_names;
1362    pl = cmd->clone->par;
1363    current_sequ->l_expr = command_par_expr("l", cmd->clone);
1364    current_sequ->length = command_par_value("l", cmd->clone);
1365    current_sequ->add_pass = command_par_value("add_pass", cmd->clone);
1366    if (current_sequ->l_expr == NULL && sequence_length(current_sequ) == zero)
1367      fatal_error("missing length for sequence:", toks[aux_pos]);
1368    pos = name_list_pos("refpos", nl);
1369    if (nl->inform[pos])
1370      current_sequ->refpos = permbuff(pl->parameters[pos]->string);
1371    pos = name_list_pos("next_sequ", nl);
1372    if (nl->inform[pos])
1373      current_sequ->next_sequ = permbuff(pl->parameters[pos]->string);
1374    current_node = NULL;
1375    if (occ_list == NULL)
1376      occ_list = new_name_list("occ_list", 10000);  /* for occurrence count */
1377    else occ_list->curr = 0;
1378    if (current_sequ->cavities != NULL)  current_sequ->cavities->curr = 0;
1379    else current_sequ->cavities = new_el_list(100);
1380    pos = name_list_pos("marker", defined_commands->list);
1381    clone = clone_command(defined_commands->commands[pos]);
1382    sprintf(c_dum->c, "%s$start", current_sequ->name);
1383    el = make_element(c_dum->c, "marker", clone, 0);
1384    make_elem_node(el, 1);
1385    current_sequ->start = current_node;
1386    current_sequ->share = aux_pos;
1387  }
1388}
1389
1390int
1391aperture_count(struct sequence* sequ)
1392  /* returns max. number of aperture parameters needed for sequence */
1393{
1394  int i = 0, n = 0;
1395  char* p;
1396  struct node* node = sequ->start;
1397  while (node != NULL)
1398  {
1399    if ((node->p_elem)&&(p = command_par_string("apertype", node->p_elem->def)))
1400    {
1401      while(aperture_types[i][0] != ' ')
1402      {
1403        if (strcmp(p, aperture_types[i]) == 0)
1404        {
1405          if (n < aperture_npar[i]) n = aperture_npar[i];
1406          break;
1407        }
1408        i++;
1409      }
1410    }
1411    if (node == sequ->end) break;
1412    node = node->next;
1413  }
1414  return n;
1415}
1416
1417void
1418enter_sequ_reference(struct in_cmd* cmd, struct sequence* sequ)
1419  /* enters a sequence in a sequence */
1420{
1421  struct name_list* nl = cmd->clone->par_names;
1422  struct command_parameter_list* pl = cmd->clone->par;
1423  int i, pos, k = 1;
1424  double at;
1425  if (nl->inform[name_list_pos("at", nl)] == 0)
1426    fatal_error("sequence reference without 'at':",
1427                join(cmd->tok_list->p, cmd->tok_list->curr));
1428  at = command_par_value("at", cmd->clone);
1429  if ((i = name_list_pos(cmd->tok_list->p[0], occ_list)) < 0)
1430    i = add_to_name_list(permbuff(cmd->tok_list->p[0]), k, occ_list);
1431  else k = ++occ_list->inform[i];
1432  make_sequ_node(sequ, k);
1433  current_node->at_value = at;
1434  current_node->at_expr = command_par_expr("at", cmd->clone);
1435  pos = name_list_pos("from", nl);
1436  if (nl->inform[pos])
1437    current_node->from_name = permbuff(pl->parameters[pos]->string);
1438  if (current_sequ->nested <= sequ->nested)
1439    current_sequ->nested = sequ->nested + 1;
1440}
1441
1442void
1443exec_dumpsequ(struct in_cmd* cmd)
1444  /* writes a sequence out */
1445{
1446  struct name_list* nl = cmd->clone->par_names;
1447  struct command_parameter_list* pl = cmd->clone->par;
1448  int level, spos, pos = name_list_pos("sequence", nl);
1449  struct sequence* sequ = NULL;
1450  char* name = NULL;
1451  if (nl->inform[pos] == 0)  sequ = current_sequ;
1452  else
1453  {
1454    name = pl->parameters[pos]->string;
1455    if ((spos = name_list_pos(name, sequences->list)) >= 0)
1456      sequ = sequences->sequs[spos];
1457  }
1458  pos = name_list_pos("level", nl);
1459  if (nl->inform[pos] > 0) level = pl->parameters[pos]->double_value;
1460  else level = 0;
1461  if (sequ != NULL) dump_exp_sequ(sequ, level);
1462}
1463
1464void
1465exec_save(struct in_cmd* cmd)
1466  /* save a sequence with all necessary parameters and sub-sequences */
1467{
1468  int i, n = 0, pos, prev = 0, beam_save = log_val("beam", cmd->clone),
1469    mad8 = log_val("mad8", cmd->clone),
1470    bare = log_val("bare", cmd->clone), all_sequ = 0;
1471  char *name, *filename, *new_name = NULL;
1472  struct element* el;
1473  struct el_list* ell;
1474  struct node* c_node;
1475  struct sequence* sequ;
1476  struct sequence_list *sql, *sqo;
1477  struct var_list* varl;
1478  struct name_list* nl = cmd->clone->par_names;
1479  struct command_parameter_list* pl = cmd->clone->par;
1480  struct command_parameter* clp;
1481  default_beam_saved = 0;
1482  i = name_list_pos("file", nl);
1483  if (nl->inform[i] == 0)
1484  {
1485    warning("save without file:", "ignored");
1486    return;
1487  }
1488  filename = pl->parameters[i]->string;
1489  if ((out_file = fopen(filename, "w")) == NULL)
1490  {
1491    warning("cannot open output file:", filename);
1492    return;
1493  }
1494/* get export name for sequence (newname in SAVE) HG 15.10.07 */
1495  i = name_list_pos("newname", nl);
1496  if (nl->inform[i] != 0) new_name = pl->parameters[i]->string;
1497/* end -- export name for sequence (newname in SAVE) HG 15.10.07 */
1498  warning("SAVE makes all previous USE invalid !", " ");
1499  pos = name_list_pos("sequence", nl);
1500  clp = cmd->clone->par->parameters[pos];
1501  if (nl->inform[pos] == 0)  /* no sequence given, all sequences saved */
1502  {
1503    sqo = sequences; all_sequ = 1;
1504  }
1505  else
1506  {
1507    sqo = new_sequence_list(20);
1508    for (i = 0; i < clp->m_string->curr; i++)
1509    {
1510      name = clp->m_string->p[i];
1511      if ((pos = name_list_pos(name, sequences->list)) < 0)
1512        warning("unknown sequence ignored:", name);
1513      else add_to_sequ_list(sequences->sequs[pos], sqo);
1514    }
1515  }
1516  /* now do it */
1517  sql = new_sequence_list(20);
1518  ell = new_el_list(10000);
1519  if (all_sequ == 0)  varl = new_var_list(2000);
1520  else varl = clone_var_list(variable_list); /* write all variables */
1521  for (pos = 0; pos < sqo->curr; pos++)
1522  {
1523    sequ = sqo->sequs[pos];
1524    add_to_sequ_list(sequ, sql);
1525    /* check for inserted sequences, flatten if necessary  - HG 23.3.04 */
1526    c_node = sequ->start;
1527    while(c_node != NULL)
1528    {
1529      if (c_node->p_sequ != NULL)
1530      {
1531        warning("structured sequence flattened:", sequ->name);
1532        seq_edit_ex(sequ);
1533        seq_flatten(edit_sequ);
1534        seq_end_ex();
1535        break;
1536      }
1537      if (c_node == sequ->end) break;
1538      c_node = c_node->next;
1539    }
1540    /* end mod - HG 23.3.04 */
1541    if (beam_save && bare == 0)
1542    {
1543      if (mad8 == 0) save_beam(sequ, out_file); /* only mad-X */
1544      else warning("when mad-8 format requested,","beam not saved");
1545    }
1546  }
1547  for (i = sql->curr-1; i >= 0; i--) /* loop over sequences, get elements */
1548  {
1549/* set export name for sequence (newname in SAVE) HG 15.10.07 */
1550    if (new_name == NULL)
1551      strcpy(sql->sequs[i]->export_name, sql->sequs[i]->name);
1552    else strcpy(sql->sequs[i]->export_name, new_name);
1553/* end mod HG 15.10.07 */
1554    c_node = sql->sequs[i]->start;
1555    while (c_node != NULL)
1556    {
1557      if ((el = c_node->p_elem) != NULL && strchr(el->name, '$') == NULL
1558          && strcmp(el->base_type->name, "drift") != 0)
1559      {
1560        while (el->base_type != el)
1561        {
1562          add_to_el_list(&el, 0, ell, 0);
1563          el = el->parent;
1564        }
1565      }
1566      if (c_node == sql->sequs[i]->end) break;
1567      c_node = c_node->next;
1568    }
1569  }
1570  if (all_sequ == 0)
1571  {
1572    while (prev < ell->curr) /* loop over elements, get variables -
1573                                recursive, since elements may be added */
1574    {
1575      prev = ell->curr;
1576      for (i = n; i < ell->curr; i++)
1577        fill_elem_var_list(ell->elem[i], ell, varl);
1578      n = prev;
1579    }
1580    fill_sequ_var_list(sql, ell, varl); /* variables for positions */
1581  }
1582  if (mad8)
1583  {
1584    if (bare == 0)
1585    {
1586      write_vars_8(varl, save_select, out_file);
1587      write_elems_8(ell, save_select, out_file);
1588    }
1589    for (pos = 0; pos < sql->curr; pos++)
1590    {
1591      sequ = sql->sequs[pos];
1592      all_node_pos(sequ);
1593      sequ->ex_nodes = new_node_list(2*sequ->nodes->curr);
1594      expand_sequence(sequ, 0);
1595      export_sequ_8(sequ, save_select, out_file);
1596      sequ->ex_nodes = delete_node_list(sequ->ex_nodes);
1597    }
1598  }
1599  else
1600  {
1601    if (bare == 0)
1602    {
1603      write_vars(varl, save_select, out_file);
1604      write_elems(ell, save_select, out_file);
1605    }
1606    write_sequs(sql, save_select, out_file);
1607  }
1608  fclose(out_file);
1609  if (sqo != sequences) sqo = delete_sequence_list(sqo);
1610  sql = delete_sequence_list(sql);
1611  ell = delete_el_list(ell);
1612  varl = delete_var_list(varl);
1613  current_sequ = NULL;
1614}
1615
1616void
1617exec_extract(struct in_cmd* cmd)
1618  /* "extract" command - extract part of  sequence from marker_1 to marker_2 */
1619{
1620  struct name_list* nl = cmd->clone->par_names;
1621  struct command_parameter_list* pl = cmd->clone->par;
1622  struct sequence *split_sequ = NULL, *part;
1623  int i, j;
1624  char *name = NULL, *refpos = NULL;
1625  char newname[NAME_L];
1626  struct node *from, *to;
1627  /*
1628    start command decoding
1629  */
1630  i = name_list_pos("sequence", nl);
1631  if(nl->inform[i]) /* sequence specified */
1632  {
1633    name = pl->parameters[i]->string;
1634    if ((j = name_list_pos(name, sequences->list)) > -1)
1635      split_sequ = sequences->sequs[j];
1636    else
1637    {
1638      warning("unknown sequence ignored:", name);
1639      return;
1640    }
1641  }
1642  i = name_list_pos("newname", nl);
1643  if (nl->inform[i] == 0) sprintf(newname, "%s_1", name);
1644  else strcpy(newname, pl->parameters[i]->string);
1645  i = name_list_pos("from", nl);
1646  if (nl->inform[i] == 0)
1647  {
1648    warning("no 'from' marker given", " ");
1649    return;
1650  }
1651  sprintf(c_dum->c, "%s:1", pl->parameters[i]->string);
1652  if ((j = name_list_pos(c_dum->c, split_sequ->nodes->list)) > -1)
1653    from = split_sequ->nodes->nodes[j];
1654  else
1655  {
1656    warning("not in sequence:", pl->parameters[i]->string);
1657    return;
1658  }
1659  i = name_list_pos("to", nl);
1660  if (nl->inform[i] == 0)
1661  {
1662    warning("no 'to' marker given", " ");
1663    return;
1664  }
1665  if (strchr(pl->parameters[i]->string, '$'))
1666  {
1667    warning("extract: use of internal markers forbidden:", 
1668            pl->parameters[i]->string);
1669    warning("sequence extraction aborted"," ");
1670    return;
1671  }
1672  sprintf(c_dum->c, "%s:1", pl->parameters[i]->string);
1673  if ((j = name_list_pos(c_dum->c, split_sequ->nodes->list)) > -1)
1674    to = split_sequ->nodes->nodes[j];
1675  else
1676  {
1677    warning("not in sequence:", pl->parameters[i]->string);
1678    return;
1679  }
1680  i = name_list_pos("refpos", nl);
1681  if (nl->inform[i]) refpos = pl->parameters[i]->string;
1682  /*
1683    end of command decoding - action!
1684  */
1685  part = extract_sequence(newname, split_sequ, from, to, refpos);
1686  add_to_sequ_list(part, sequences);
1687}
1688
1689void
1690expand_curr_sequ(int flag)
1691  /* expands the current sequence, i.e. flattens it, inserts drifts etc. */
1692  /* The sequence length is updated - new feature HG 26.5.03 */
1693{
1694  char rout_name[] = "expand_curr_sequ";
1695  struct node* c_node;
1696  int j;
1697  current_sequ->end->at_value = current_sequ->end->position = sequence_length(current_sequ);
1698
1699  if (current_sequ->ex_start != NULL) {
1700    current_sequ->ex_nodes = delete_node_list(current_sequ->ex_nodes);
1701    current_sequ->ex_start = delete_node_ring(current_sequ->ex_start);
1702    current_sequ->orbits = delete_vector_list(current_sequ->orbits);
1703  }
1704
1705  if (current_sequ->ex_start == NULL) {
1706    use_count++;
1707    if (occ_list == NULL)
1708      occ_list = new_name_list("occ_list",10000);  /* for occurrence count */
1709    else
1710      occ_list->curr = 0;
1711    make_occ_list(current_sequ);
1712    all_node_pos(current_sequ);
1713    current_sequ->ex_nodes = new_node_list(2*current_sequ->nodes->curr);
1714    expand_sequence(current_sequ, flag);
1715    current_sequ->n_nodes = add_drifts(current_sequ->ex_start, current_sequ->ex_end);
1716    if (current_sequ->all_nodes != NULL) myfree(rout_name, current_sequ->all_nodes);
1717    current_sequ->all_nodes = mymalloc(rout_name, current_sequ->n_nodes * sizeof(struct node*));
1718    c_node = current_sequ->ex_start;
1719    for (j = 0; j < current_sequ->n_nodes; j++) {
1720      current_sequ->all_nodes[j] = c_node;
1721      c_node = c_node->next;
1722    }
1723  }
1724  set_node_bv(current_sequ); /* set bv factors for all nodes */
1725  if (current_range)
1726    set_range(current_range, current_sequ);
1727  else {
1728    current_sequ->range_start = current_sequ->ex_start;
1729    current_sequ->range_end = current_sequ->ex_end;
1730  }
1731}
1732
1733void
1734reset_errors(struct sequence* sequ)
1735  /* zeros the sel_err node flag for all nodes of an expanded sequence */
1736{
1737  struct node* c_node;
1738  if (sequ != NULL && sequ->ex_start != NULL && sequ->ex_end != NULL)
1739  {
1740    c_node = sequ->ex_start;
1741    while (c_node != NULL)
1742    {
1743      c_node->sel_err = 0;
1744      if (c_node == sequ->ex_end) break;
1745      c_node = c_node->next;
1746    }
1747  }
1748}
1749
1750void
1751add_to_sequ_list(struct sequence* sequ, struct sequence_list* sql)
1752  /* adds sequence sequ to sequence list sql */
1753{
1754  int i;
1755  int firstfreeslot = -1;
1756  for (i = 0; i < sql->curr; i++) if (sql->sequs[i] == sequ)  return;
1757
1758  /*printf("add_to_sequ_list %s \n",sequ->name);*/
1759
1760  for (i = 0; i < sql->curr; i++)
1761  {
1762    if (sql->sequs[i] == 0x0)
1763    {
1764      /*printf("add_to_sequ_list: pos %d is NULL\n",i);*/
1765      firstfreeslot = i;
1766      continue;
1767    }
1768   
1769    if (strcmp(sql->sequs[i]->name, sequ->name) == 0)
1770    {
1771      /*printf("add_to_sequ_list sequence with this name is already in: %s \n",sequ->name);*/
1772      sql->sequs[i] = sequ;
1773      sql->list->names[i] = sequ->name;
1774      return;
1775    }
1776  }
1777 
1778  if (firstfreeslot >= 0)
1779  {/*This protects agains problems sequence redefinition*/
1780    /*printf("add_to_sequ_list: adding at found free slot\n");*/
1781    sql->sequs[firstfreeslot] = sequ;
1782  }
1783  else
1784  { 
1785    /*printf("add_to_sequ_list: adding at new slot\n");*/
1786    if (sql->curr == sql->max) grow_sequence_list(sql);
1787    sql->sequs[sql->curr++] = sequ;
1788  } 
1789
1790  add_to_name_list(sequ->name, 0, sql->list);
1791 
1792}
1793
1794void
1795reset_sector(struct sequence* sequ, int val)
1796  /* sets node->sel_sector = val for all nodes of an expanded sequence */
1797{
1798  struct node* c_node;
1799  if (sequ != NULL && sequ->ex_start != NULL && sequ->ex_end != NULL)
1800  {
1801    c_node = sequ->ex_start;
1802    while (c_node != NULL)
1803    {
1804      c_node->sel_sector = val;
1805      if (c_node == sequ->ex_end) break;
1806      c_node = c_node->next;
1807    }
1808  }
1809}
1810
1811int
1812restart_sequ(void)
1813{
1814  current_node = current_sequ->range_start;
1815  return 1;
1816}
1817
1818void
1819seq_edit_main(struct in_cmd* cmd)
1820  /* controls sequence editing */
1821{
1822  int k = cmd->decl_start - 1;
1823  char** toks = cmd->tok_list->p;
1824  if (strcmp(toks[k], "seqedit") == 0)  seq_edit(cmd);
1825  else if(edit_is_on)
1826  {
1827    if (strcmp(toks[k], "install") == 0)  seq_install(cmd);
1828    else if (strcmp(toks[k], "move") == 0)  seq_move(cmd);
1829    else if (strcmp(toks[k], "remove") == 0)  seq_remove(cmd);
1830    else if (strcmp(toks[k], "cycle") == 0)  seq_cycle(cmd);
1831    else if (strcmp(toks[k], "flatten") == 0)  seq_flatten(edit_sequ);
1832    else if (strcmp(toks[k], "reflect") == 0)  seq_reflect(cmd);
1833    else if (strcmp(toks[k], "replace") == 0)  seq_replace(cmd);
1834    else if (strcmp(toks[k], "endedit") == 0)  seq_end(cmd);
1835  }
1836  else warning("seqedit command outside edit", "ignored");
1837}
1838
1839int
1840set_enable(char* type, struct in_cmd* cmd)
1841{
1842  char* name;
1843  struct command_parameter* cp;
1844  struct name_list* nl = cmd->clone->par_names;
1845  struct command_parameter_list* pl = cmd->clone->par;
1846  struct sequence* sequ;
1847  struct node* nodes[2];
1848  struct node* c_node;
1849  int pos, n, status, count = 0; // k, // not used
1850  pos = name_list_pos("sequence", nl);
1851  if(nl->inform[pos]) /* sequence specified */
1852  {
1853    cp = cmd->clone->par->parameters[pos];
1854    if ((n = name_list_pos(cp->string, sequences->list)) >= 0)
1855      sequ = sequences->sequs[n];
1856    else
1857    {
1858      warning(cp->string," :sequence not found, skipped");
1859      return 0;
1860    }
1861  }
1862  else sequ = current_sequ;
1863  if (sequ->ex_start == NULL)
1864  {
1865    warning(sequ->name," :sequence not USEed, skipped");
1866    return 0;
1867  }
1868  pos = name_list_pos("status", nl);
1869  if (pos > -1 && nl->inform[pos])  /* parameter has been read */
1870  {
1871    name = pl->parameters[pos]->string;
1872    status = strcmp(name, "on") == 0 ? 1 : 0;
1873  }
1874  else status = 1;
1875  pos = name_list_pos("range", nl);
1876  if (pos > -1 && nl->inform[pos])  /* parameter has been read */
1877  {
1878    name = pl->parameters[pos]->string;
1879    if (get_ex_range(name, sequ, nodes) == 0) // (k = // not used
1880    {
1881      nodes[0] = NULL; nodes[1] = NULL;
1882    }
1883  }
1884  else
1885  {
1886    nodes[0] = sequ->ex_start; nodes[1] = sequ->ex_end;
1887  }
1888  c_node = nodes[0];
1889  while (c_node)
1890  {
1891    if (strstr(c_node->base_name, type) &&
1892        pass_select(c_node->p_elem->name, cmd->clone) != 0)
1893    {
1894      c_node->enable = status; count++;
1895    }
1896    if (c_node == nodes[1]) break;
1897    c_node = c_node->next;
1898  }
1899  return count;
1900}
1901
1902
Note: See TracBrowser for help on using the repository browser.