Skip to content

Commit c1106fd

Browse files
committed
Merge branch 'dev' into object_sepmeth
2 parents 4e92b23 + f122602 commit c1106fd

13 files changed

+247
-108
lines changed

src/madl_element.mad

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ local Element = object 'element' {
3636
l_mag=\s s.l, l_elec=\s s.l, l_rad=\s s.l, l_mech=\s s.l, -- aliases
3737
}
3838

39+
-- identity -------------------------------------------------------------------o
40+
3941
local _id = {}
4042

4143
local function is_element (a)
@@ -46,8 +48,8 @@ end
4648
-- flags ----------------------------------------------------------------------o
4749

4850
M.flags = {
49-
implicit = Element.first_free_flag, -- inherited from object
50-
selected = Element.first_free_flag+1,
51+
selected = Element.first_free_flag,
52+
implicit = Element.first_free_flag+1, -- inherited from object
5153
observe = Element.first_free_flag+2,
5254
layout = Element.first_free_flag+3,
5355
layangle = Element.first_free_flag+4,
@@ -57,13 +59,15 @@ Element.first_free_flag = Element.first_free_flag+5 -- overridden in Element
5759

5860
-- members --------------------------------------------------------------------o
5961

60-
local implicit, selected in M.flags
62+
local implicit, observe, selected in M.flags
6163

6264
Element :set_methods {
63-
is_implicit = \s -> test_flag(s, implicit),
6465
is_selected = \s,f -> test_flag(s, f or selected),
6566
select = \s,f -> set_flag(s, f or selected),
6667
deselect = \s,f -> clear_flag(s, f or selected),
68+
-- specializations
69+
is_implicit = \s -> test_flag(s, implicit),
70+
is_observed = \s -> test_flag(s, observe ),
6771

6872
} :set_metamethods ({
6973
-- identity
@@ -169,10 +173,11 @@ M.vkicker.ksl = \s -> { s. kick or s.vkick or 0 }
169173

170174
-- env ------------------------------------------------------------------------o
171175

172-
local is_implicit, is_selected in Element
176+
local is_implicit, is_observed, is_selected in Element
173177

174178
MAD.typeid.is_element = is_element
175179
MAD.typeid.is_implicit = is_implicit
180+
MAD.typeid.is_observed = is_observed
176181
MAD.typeid.is_selected = is_selected
177182

178183
-- end ------------------------------------------------------------------------o

src/madl_gphys.mad

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323

2424
-- locals ---------------------------------------------------------------------o
2525

26-
local matrix in MAD
26+
local matrix, trace in MAD
2727
local is_positive, is_matrix, is_cvector, wrestrict in MAD.typeid
28-
local assertf in MAD.utility
28+
local assertf, num2str in MAD.utility
2929
local twopi in MAD.constant
3030
local abs, sqrt, atan2 in math
3131

32-
local dp_tol = 1e-12
32+
local dp_tol = 1e-12
33+
local symp_tol = 1e-12
3334

3435
-- helpers --------------------------------------------------------------------o
3536

@@ -188,6 +189,11 @@ end
188189
function gphys.normal1 (R)
189190
chkeigsiz(R)
190191

192+
local symperr = R:symperr()
193+
-- if symperr > symp_tol then
194+
trace(0, "symplectic deviation: %s", num2str(symperr))
195+
-- end
196+
191197
-- get eigenvalues and eigenvectors of R
192198
local W, A, V, info = R:eigen()
193199
-- print("\ninfo=", info)
@@ -218,6 +224,9 @@ function gphys.normal1 (R)
218224
gphys.phas_eigen(A)
219225
-- A:print('A')
220226

227+
-- check one-turn-map normalisation
228+
R :print('R') ; (1/A * R * A) :print('N = A^-1 R A ')
229+
221230
return A, V, W, info
222231
end
223232

src/madl_madx.mad

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
-- locals ---------------------------------------------------------------------o
2525

2626
local object, warn in MAD
27-
local assertf in MAD.utility
27+
local assertf, openfile in MAD.utility
2828
local bind1st in MAD.gfunc
29-
local is_nil, is_number, is_string, is_instanceOf in MAD.typeid
29+
local is_nil, is_number, is_string, is_callable, is_instanceOf in MAD.typeid
3030

3131
assert(is_nil(MADX), "MADX environment already defined")
3232

@@ -229,14 +229,12 @@ end
229229
cls[elm] = cls_name : class of element
230230
]]--
231231

232-
local function load_file (madx, file_in, file_out)
232+
local function load2madx (madx, src, dst)
233233
assert(madx == MADX or is_instanceOf(madx, MADX), "invalid MADX environment")
234-
assert(is_string(file_in) , "invalid input file name")
235-
assert(is_string(file_out) or is_nil(file_out) , "invalid ouput file name")
236234

237235
-- compile directly in memory (no translation)
238-
if string.sub(file_in, -4) == '.mad' then
239-
MADX:load_env(file_in)
236+
if is_callable(src) or is_string(src) and string.sub(src, -4) == '.mad' then
237+
MADX:load_env(src)
240238
return
241239
end
242240

@@ -246,10 +244,9 @@ local function load_file (madx, file_in, file_out)
246244
wrn=madx.option.warn, madx=madx }
247245

248246
-- load file
249-
local inf = assert( io.open(file_in) )
247+
local inf = openfile(src, 'r')
250248
local out = {
251249
string.format("-- Generated by MAD %s %s", MAD.env.version, os.date()),
252-
-- string.format("%s:open_env()\n", madx.name),
253250
}
254251

255252
for line in inf:lines() do
@@ -259,13 +256,13 @@ local function load_file (madx, file_in, file_out)
259256
line = convert_statements (env, line)
260257
out[#out+1] = line
261258
end
262-
-- out[#out+1] = string.format("\n%s:close_env()", madx.name)
263-
inf:close()
259+
if is_string(src) then inf:close() else inf:flush() end
264260

265261
-- save to file
266-
if file_out then
267-
local outf = assert( io.open(file_out, "w") )
262+
if dst then
263+
local outf = openfile(dst, 'w', '.mad')
268264
for i,s in ipairs(out) do outf:write(s, '\n') end
265+
if is_string(dst) then outf:close() else outf:flush() end
269266
end
270267

271268
-- compile in memory
@@ -279,7 +276,6 @@ end
279276
-- MADX helpers ---------------------------------------------------------------o
280277

281278
local sinc in MAD.gmath
282-
local is_callable in MAD.typeid
283279

284280
--[[
285281
l_arc = A*R
@@ -315,7 +311,7 @@ local MADX = object 'MADX' {
315311

316312
-- load madx definition
317313
MADX:set_methods {
318-
load = load_file,
314+
load = load2madx,
319315
}
320316

321317
-- math functions, see mad_dict.c from MAD-X source

src/madl_mtable.mad

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,12 +642,12 @@ local function range_of (tbl, rng_, ref_, dir_)
642642
stop , istop = start, istart
643643
elseif is_string(rng_) then
644644
local s1, i2 = strsplit(rng_, "/" )
645-
local s2 = i2 > 0 and strtrim(rng_, i2+1) or nil
645+
local s2 = i2 == 0 and s1 or strtrim(rng_, i2+1)
646646
start, stop = s1, s2
647647
elseif is_range(rng_) then
648648
start, stop = rng_:ranges()
649649
elseif is_table(rng_) then
650-
start, stop, ref_ = rng_[1], rng_[2], ref_ or rng_[3]
650+
start, stop, ref_ = rng_[1], rng_[2] or rng_[1], ref_ or rng_[3]
651651
else error "invalid argument #2 (integer, string, table or range expected)"
652652
end
653653
if not is_number(rng_) then
@@ -763,6 +763,22 @@ local function set (tbl, row, col, val, cnt_)
763763
end
764764
end
765765

766+
--- cleaning -------------------------------o
767+
768+
local function clr_dat (tbl)
769+
assert(is_mtable(tbl), "invalid argument #1 (mtable expected)")
770+
local data = var_raw(tbl,_data)
771+
assert(not (data.ro or tbl:is_readonly()), "invalid write access to readonly mtable")
772+
for i=1,data.nc-data.ng do
773+
if is_table(data[i])
774+
then table.clear(data[i])
775+
else data[i]:zeros():_reshapeto(0)
776+
end
777+
end
778+
data.nr = 0
779+
return tbl
780+
end
781+
766782
--- columns -------------------------------o
767783

768784
local function get_col (tbl, key)
@@ -1517,6 +1533,9 @@ mtable :set_methods {
15171533
insrow = ins_row,
15181534
swprow = swp_row,
15191535

1536+
-- clear all data, keep everything else
1537+
clrdat = clr_dat,
1538+
15201539
-- sequence-like methods
15211540
name_of = name_of,
15221541
index_of = index_of,

src/madl_plot.mad

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ local function plot_unlock (folder)
9898
end
9999
os.remove(tmplock)
100100
filesys.unlock(lock)
101+
lock:close()
101102
end
102103

103104
-- clear the list of handle of non-existing file
@@ -304,7 +305,7 @@ end
304305

305306
local function teardown_cmd (self, file, fname)
306307
local scrdump, output in self
307-
file:flush()
308+
file:close()
308309
if output ~= false then
309310
gplot:printf("load('%s')", fname)
310311
if is_string(scrdump)

src/madl_sequence.mad

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -769,25 +769,26 @@ local function range_of (seq, rng_, ref_, dir_)
769769
elseif dir == -1 then return #seq, 1
770770
else error("invalid range direction (1 or -1 expected)")
771771
end
772-
elseif is_integer(rng_) then
773-
start, istart = rng_, index_of_idx(seq, rng_)
772+
elseif is_number(rng_) then
773+
start, istart = rng_, index_of_num(seq, rng_, dir_)
774774
stop , istop = start, istart
775775
elseif is_string(rng_) then
776776
local s1, i2 = strsplit(rng_, "/")
777-
local s2 = i2 > 0 and strtrim(rng_, i2+1) or nil
777+
local s2 = i2 == 0 and s1 or strtrim(rng_, i2+1)
778778
doidx, start, stop = true, s1, s2
779779
elseif is_range(rng_) then
780780
doidx, start, stop, step = true, rng_:ranges()
781781
dir_ = dir_ or step
782782
elseif is_table(rng_) then
783-
start, stop, ref_, dir_ = rng_[1], rng_[2], ref_ or rng_[3], dir_ or rng_[4]
783+
start, stop, ref_, dir_ = rng_[1], rng_[2] or rng_[1], ref_ or rng_[3],
784+
dir_ or rng_[4]
784785
if ref_ == 'idx' then
785786
assert(is_integer(start) and is_integer(stop),
786787
"invalid argument #2 (range of integers expected)")
787788
istart, istop = index_of_idx(seq, start), index_of_idx(seq, stop)
788789
else doidx = true
789790
end
790-
else error("invalid argument #2 (integer, string, table or range expected)")
791+
else error("invalid argument #2 (number, string, table or range expected)")
791792
end
792793
local sstart, sstop
793794
if doidx then

src/madl_survey.mad

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,14 @@ local function save_all (elm, mflw, lw_)
8080
atfill(elm, mflw, lw)
8181
end
8282

83-
local function save_elm (elm, mflw, lw_)
84-
if not is_implicit(elm) then save_all(elm, mflw, lw_) end
83+
local function save_imp (elm, mflw, lw_)
84+
if is_implicit(elm) then return end
85+
save_all(elm, mflw, lw_)
86+
end
87+
88+
local function save_obs (elm, mflw, lw_)
89+
if not is_observed(elm) then return end
90+
save_all(elm, mflw, lw_)
8591
end
8692

8793
local function make_mtable (self)
@@ -117,17 +123,20 @@ local function make_mflow (self)
117123
local iter, state, init = sequ:siter(range, nturn, sdir)
118124

119125
-- build mtable
120-
local save, nofill, implicit in self
126+
local save, nofill, observe, implicit in self
121127
assert(is_boolean(save) or is_callable(save),
122128
"invalid save (boolean or callable expected)")
123129
assert(is_boolean(nofill) , "invalid nofill (boolean expected)")
130+
assert(is_boolean(observe) , "invalid observe (boolean expected)")
124131
assert(is_boolean(implicit), "invalid implicit (boolean expected)")
125132

126133
-- saving data
127134
local mtbl, fill
128135
if save then
129136
mtbl = make_mtable(self)
130-
fill = is_callable(save) and save or implicit and save_all or save_elm
137+
fill = is_callable(save) and save or -- precedence matters!
138+
observe == true and save_obs or
139+
implicit == false and save_imp or save_all
131140
else
132141
fill = fnone
133142
end
@@ -238,33 +247,42 @@ local function exec (self)
238247
return mtbl, mflw
239248
end
240249

241-
local survey = command 'survey' {
242-
sequence=nil, -- sequence (required) (mflw)
243-
range=nil, -- range of tracking (iter)
244-
title=nil, -- title of mtable (mtbl)
245-
sdir=1, -- s-direction of tracking (1 or -1) (mflw)
246-
247-
s0=0, -- initial s (mflw)
248-
X0={0,0,0}, -- initial coordinates x, y, z (mflw)
249-
A0={0,0,0}, -- initial angles theta, phi, psi (mflw)
250+
local _na -- not applicable (see track or twiss)
250251

251-
nturn=1, -- number of turns (iter)
252-
nstep=-1, -- number of elements to track (iter)
253-
nslice=1, -- number of slice for each element (mflw)
254-
255-
save=true, -- create mtable and set fill to save data (mtbl)
256-
nofill=false, -- disable filling at the end of an element (mflw)
257-
implicit=true, -- save also implicit elements (mtbl)
258-
259-
atentry=nil, -- action to call when entering an element (mflw)
260-
atslice=nil, -- action to call after each element slices (mflw)
261-
atexit=nil, -- action to call when exiting an element (mflw)
262-
atfill=nil, -- action to call when filling a mtable row (mflw)
252+
local survey = command 'survey' {
253+
beam=_na, -- N/A (mflw)
254+
sequence=nil, -- sequence (required) (mflw)
255+
range=nil, -- range of tracking (iter)
256+
title=nil, -- title of mtable (mtbl)
257+
sdir=1, -- s-direction of tracking (1 or -1) (mflw)
258+
259+
s0=0, -- initial s (mflw)
260+
X0={0,0,0}, -- initial coordinates x, y, z (mflw)
261+
A0={0,0,0}, -- initial angles theta, phi, psi (mflw)
262+
263+
mapdef=_na, -- N/A (mflw)
264+
mapsave=false, -- save W in the mtable (mflw)
265+
266+
nturn=1, -- number of turns (iter)
267+
nstep=-1, -- number of elements to track (iter)
268+
nslice=1, -- number of slice for each element (mflw)
269+
method=_na, -- N/A (mflw)
270+
totalpath=_na, -- N/A (mflw)
271+
272+
save=true, -- create mtable and set fill to save data (mtbl)
273+
nofill=false, -- disable filling at the end of an element (mflw)
274+
observe=false, -- save only observed elements (mtbl)
275+
implicit=true, -- save also implicit elements (mtbl)
276+
277+
atentry=nil, -- action to call when entering an element (mflw)
278+
atslice=nil, -- action to call after each element slices (mflw)
279+
atexit=nil, -- action to call when exiting an element (mflw)
280+
atfill=nil, -- action to call when filling a mtable row (mflw)
263281

264282
mflow=nil, -- current mflow, exclusive with other attributes except nstep
265283

266-
exec=exec, -- command to execute upon children creation
267-
} :set_readonly() -- reference survey command is readonly
284+
exec=exec, -- command to execute upon children creation
285+
} :set_readonly() -- reference survey command is readonly
268286

269287
-- end ------------------------------------------------------------------------o
270288
return { survey = survey }

0 commit comments

Comments
 (0)