# Upgrading from 0.6.x Release 0.7 changes what a field monitor hands out. A time or frequency monitor used to average the solver's staggered samples onto cell centres the moment it recorded them and to return those averages as a dictionary of arrays. It now keeps the solver's own samples — the grid quantities on the Yee positions of its region — and hands them out as a field container; the averages are one call away and computed only where you ask for them. The project store changed with it, so runs written by 0.6.x cannot be read by 0.7 and are refused with a message. ## Quick reference | 0.6.x | 0.7 | If you leave it alone | |---|---|---| | `mon.data["Ez"]` (time monitor) | `mon.recording.cell_centred(["Ez"], squeeze=True)["Ez"]` | `AttributeError: 'MonitorFieldTime' object has no attribute 'data'` | | `mon.data["Ez"]` (frequency monitor) | `mon.spectrum.cell_centred(["Ez"], squeeze=True)["Ez"]` | `AttributeError` | | `mon.data_raw["Ez"]` | `mon.spectrum_raw.cell_centred(["Ez"], squeeze=True)["Ez"]` | `AttributeError` | | `mon.component("Ez")` | `mon.recording.cell_centred(["Ez"], squeeze=True)["Ez"]`, or `mon.recording.component("Ez")` for the staggered samples | `AttributeError` | | `mon.region.xc`, `.yc`, `.zc` | `mon.recording.cell_centres[0]`, `[1]`, `[2]` (`.spectrum.cell_centres` for a frequency monitor) | `AttributeError` | | `mon.region.ndim` | `sum(n > 1 for n in mon.recording.shape)` | `AttributeError` | | `mon.t` | unchanged — but see below | — | | `project.monitors[...]` readers: `.data`, `.component(...)` | `.recording` / `.spectrum` as above; `.frame(i)` reads one frame | `AttributeError` | | `mon.plot(...)`, `mon.interact(...)`, `mon.show(...)` | unchanged | — | | `model.plot(...)` | `model.show(...)` (0.8; `plot` draws into matplotlib everywhere else) | a `DeprecationWarning`, the view opens as before | | `runs//fields.xdmf` | `runs//paraview/.pvd` with one `.vtr` per frame, written by `project.export_paraview()` (0.8: no longer at the run's close) | the XDMF file is not written | | a project written by 0.6.x | re-run it | `ProjectSchemaError: schema version '2.0' is not supported` | `squeeze=True` drops the spatial axes of length one, which is what the old dictionaries did on their own: a plane monitor reads `(n_frames, nu, nv)`, a line `(n_frames, n)`, a point `(n_frames,)`. Without it every array is `(n_frames, nx, ny, nz)`. ## What the containers give you `FieldRecording` (time) and `FieldSpectrum` (frequency) live in `magnelio.fields` and are described in the chapter {doc}`methods/sources-monitors`. In short: - `frame(i)`, `at_time(t)`, `at_frequency(f)` — one instant as a `FieldState`, the same object an eigenmode hands out, so a recorded frame goes straight into `SourceFieldInitial` for a restart or a ring-down. - `component(name)` — the staggered samples themselves, `(n_frames, *Yee shape)`, E in V/m and H in A/m. - `cell_centred(...)`, `cell_centres` — the averages and their positions, for whole frames or a sub-box. - `times`, `times_h` — the instants of the electric and of the magnetic field; the latter lies half a time step later, which the old dictionary silently ignored. - `plot(...)`, `show(...)` — the slice plots and the 3D view, frame by frame. ## Two numbers that moved **The instant of a frame.** The solver calls the monitors after it has stepped the electric field to `t + dt`; a 0.6.x time monitor labelled that frame `t`, one step early. A frame is now stamped with the electric field's own instant, and `times_h` states the magnetic one. A request at `t = 0` is served by the first frame the solver hands out, at `dt` — the field at `t = 0` is identically zero and never recorded. A recording schedule finer than the time step yields one frame per step, where 0.6.x repeated the same snapshot under several labels. **The dual widths of a region.** The samples of `H` at the two boundary nodes of a region cut out of the grid carry the dual lengths of the *full* grid; a container built from such a region keeps them, so the cell-centred averages are what they were. You will not see a change here; it is what made the first point possible without one. The frequency monitor's time stamps are unchanged: its transform samples the same instants as the port recorder, as before. The *sign* of its exponent changed one release later — see {doc}`migration-0.8`. ## Why The record-time average was a filter, and a filter is not undone. It smeared the tangential field on a conductor face and the normal field across a dielectric interface into the neighbouring cells; it left no way to compute the stored energy or the Poynting flux from a recording, both of which are identities on the staggered samples; and it made a recorded frame unusable as the initial field of another run. Keeping the solver's own samples removes all three limits at once, and it is what the commercial suites do as well — store the solver's result, interpolate for the picture. The averaging still exists, exactly as it was; it moved from the recording to the reading.