ARTS 2.5.9 (git: 825fa5f2)
workspace_ng.cc
Go to the documentation of this file.
1/* Copyright (C) 2004-2012 Oliver Lemke <olemke@core-dump.info>
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License as
5 published by the Free Software Foundation; either version 2 of the
6 License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
16 USA. */
17
25#include "workspace_ng.h"
26#include "debug.h"
27#include "tokval.h"
29#include <memory>
30
31#include "agenda_class.h"
32#include "global_data.h"
34#include "wsv_aux.h"
35
36namespace global_data {
38} // namespace global_data
39
41
43 wsv_data_ptr->push_back(wsv);
44 WsvMap_ptr->operator[](wsv.Name()) = wsv_data_ptr->nelem() - 1;
45 ws.emplace_back();
46 return wsv_data_ptr->nelem() - 1;
47}
48
50 if (ws[i].size()) {
51 ws[i].pop();
52 emplace(i);
53 }
54}
55
57 static const auto agenda_index = global_data::WsvGroupMap.at("Agenda");
58
60
61 if (ws[i].size()) {
62 wsvs.wsv = workspace_memory_handler.duplicate((*wsv_data_ptr)[i].Group(),
63 ws[i].top().wsv);
64 wsvs.initialized = true;
65 } else {
66 if ((*wsv_data_ptr)[i].Group() == agenda_index) {
67 wsvs.wsv = std::make_shared<Agenda>(*this);
68 } else {
69 wsvs.wsv = workspace_memory_handler.allocate((*wsv_data_ptr)[i].Group());
70 }
71 wsvs.initialized = false;
72 }
73 ws[i].push(std::move(wsvs));
74}
75
77 : std::enable_shared_from_this<Workspace>(),
78 ws(workspace.ws.nelem()),
79 wsv_data_ptr(workspace.wsv_data_ptr),
80 WsvMap_ptr(workspace.WsvMap_ptr),
81 original_workspace(workspace.original_workspace) {
82 for (Index i = 0; i < workspace.ws.nelem(); i++) {
83 if (workspace.ws[i].size() && workspace.ws[i].top().wsv) {
85 wsvs.wsv = workspace.ws[i].top().wsv;
86 wsvs.initialized = workspace.ws[i].top().initialized;
87 ws[i].push(std::move(wsvs));
88 }
89 }
90}
91
93 for (Index i=0; i<nelem(); i++) {
94 if (is_initialized(i)) {
95 auto group = wsv_data_ptr->at(i).Group();
96
97 if (group == WorkspaceGroupIndexValue<Agenda>) {
98 Agenda& ag = *static_cast<Agenda*>((*this)[i].get());
99 ag.set_workspace(*this);
100 } else if (group == WorkspaceGroupIndexValue<ArrayOfAgenda>) {
101 for (auto& ag: *static_cast<ArrayOfAgenda*>((*this)[i].get())) {
102 ag.set_workspace(*this);
103 }
104 }
105 }
106 }
107}
108
110 ws[i].pop(); }
111
112void Workspace::swap(Workspace &other) noexcept {
113 ws.swap(other.ws);
114 wsv_data_ptr.swap(other.wsv_data_ptr);
115 WsvMap_ptr.swap(other.WsvMap_ptr);
116 std::swap(original_workspace, other.original_workspace);
117
118 // Must also claim Agenda ownership
119 claim_agenda_ownership();
120 other.claim_agenda_ownership();
121}
122
124 return ws[i].size() and ws[i].top().initialized;
125}
126
127Index Workspace::depth(Index i) const { return static_cast<Index>(ws[i].size()); }
128
130 static const auto agenda_index = global_data::WsvGroupMap.at("Agenda");
131
132 if ((*wsv_data_ptr)[i].Group() == agenda_index) {
133 ws[i].emplace(
134 WorkspaceVariableStruct{std::make_shared<Agenda>(*this), false});
135 } else {
136 ws[i].emplace(WorkspaceVariableStruct{
137 workspace_memory_handler.allocate((*wsv_data_ptr)[i].Group()), false});
138 }
139}
140
141std::shared_ptr<void> Workspace::operator[](Index i) {
142 if (ws[i].size() == 0) emplace(i);
143 ws[i].top().initialized = true;
144 return ws[i].top().wsv;
145}
146
148 : ws(global_data::wsv_data.nelem()),
149 wsv_data_ptr(std::make_shared<Array<WsvRecord>>(global_data::wsv_data)),
150 WsvMap_ptr(std::make_shared<map<String, Index>>(global_data::WsvMap)),
151 original_workspace(this) {
152 ARTS_ASSERT(wsv_data_ptr -> size() == WsvMap_ptr->size())
153
154 for (Index i = 0; i < (*wsv_data_ptr).nelem(); i++) {
155 if ((*wsv_data_ptr)[i].has_defaults()) {
156 push_move(i, (*wsv_data_ptr)[i].get_copy());
157 }
158 }
159}
160
161std::shared_ptr<Workspace> Workspace::deepcopy() {
162 std::shared_ptr<Workspace> out{new Workspace{}};
163 out->wsv_data_ptr = std::shared_ptr<Workspace::wsv_data_type>(
165 out->WsvMap_ptr = std::shared_ptr<Workspace::WsvMap_type>(
167 out->ws.resize(nelem());
168
169 for (Index i = 0; i < out->nelem(); i++) {
170 auto &wsv_data = out->wsv_data_ptr->operator[](i);
171
172 if (depth(i) > 0) {
173 // Set the WSV by copying the top value
174 out->ws[i].emplace(WorkspaceVariableStruct{
175 workspace_memory_handler.duplicate(
176 wsv_data_ptr->operator[](i).Group(), ws[i].top().wsv),
177 is_initialized(i)});
178
179 // Copy the agenda to the new workspace
180 if (wsv_data.Group() == WorkspaceGroupIndexValue<Agenda>) {
181 Agenda *ag = static_cast<Agenda *>(out->operator[](i).get());
182 *ag = ag->deepcopy_if(*out);
183 } else if (wsv_data.Group() == WorkspaceGroupIndexValue<ArrayOfAgenda>) {
184 for (auto &a :
185 *static_cast<ArrayOfAgenda *>(out->operator[](i).get())) {
186 a = a.deepcopy_if(*out);
187 }
188 }
189 }
190
191 // If we have any default agenda types, we must copy them to the new workspace as well
192 if (wsv_data.has_defaults()) {
193 if (wsv_data.Group() == WorkspaceGroupIndexValue<Agenda>) {
194 wsv_data.update_default_value(
195 Agenda(wsv_data.default_value()).deepcopy_if(*out));
196 }
197 if (wsv_data.Group() == WorkspaceGroupIndexValue<ArrayOfAgenda>) {
198 wsv_data.update_default_value(
199 deepcopy_if(*out, wsv_data.default_value()));
200 }
201 }
202 }
203
204 return out;
205}
206
209 out.reserve(inds.nelem());
210 for (auto ind : inds) out.push_back(wsv_data_ptr->at(ind));
211 return out;
212}
213
215 ArrayOfIndex out;
216 out.reserve(wsv_data.nelem());
217 for (auto &wsv : wsv_data) {
218 Index &pos = out.emplace_back();
219
220 if (auto ptr = WsvMap_ptr->find(wsv.Name()); ptr == WsvMap_ptr->end()) {
221 pos = add_wsv(wsv);
222 } else {
223 pos = ptr->second;
224 }
225
226 auto &existing_wsv = wsv_data_ptr->at(pos);
227
228 ARTS_USER_ERROR_IF(existing_wsv.Group() not_eq wsv.Group(),
229 "Mismatching groups")
230 }
231 return out;
232}
233
234std::shared_ptr<Workspace> Workspace::create() {
235 return std::shared_ptr<Workspace>{new Workspace{}};
236}
237
238std::shared_ptr<Workspace> Workspace::shallowcopy() const {
239 return std::shared_ptr<Workspace>{new Workspace{*this}};
240}
ArrayOfAgenda deepcopy_if(Workspace &ws, const ArrayOfAgenda &agendas)
Same as Agenda member method but for an entire array.
Declarations for agendas.
The Agenda class.
Definition: agenda_class.h:69
void set_workspace(Workspace &x)
Agenda deepcopy_if(Workspace &) const
Creates a deep copy of the agenda if necessary (i.e., different workspace)!
This can be used to make arrays out of anything.
Definition: array.h:48
Index nelem() const ARTS_NOEXCEPT
Definition: array.h:92
Handling of workspace memory.
std::shared_ptr< void > allocate(Index group_index)
Allocate workspace WSV of given group.
std::shared_ptr< void > duplicate(Index group_index, const std::shared_ptr< void > &ptr)
Duplicate workspace variable of given group.
Workspace class.
Definition: workspace_ng.h:53
std::shared_ptr< wsv_data_type > wsv_data_ptr
Definition: workspace_ng.h:76
void swap(Workspace &other) noexcept
Swap with another workspace.
Index add_wsv(const WsvRecord &wsv)
Add a new variable to this workspace.
Definition: workspace_ng.cc:42
static std::shared_ptr< Workspace > create()
Creates a new Workspace, it has to be created as a shared pointer.
void emplace(Index)
std::shared_ptr< Workspace > shallowcopy() const
Shallow copy of a Workspace, it has to be created as a shared pointer.
void pop(Index i)
Remove the topmost WSV from its stack.
void claim_agenda_ownership()
Definition: workspace_ng.cc:92
T * get(const char *name)
Retrieve a value ptr if it exist (FIXME: C++20 allows const char* as template argument)
Definition: workspace_ng.h:188
bool is_initialized(Index i) const
Checks existence of the given WSV.
map< String, Index > WsvMap_type
Definition: workspace_ng.h:78
wsv_data_type wsvs(const ArrayOfIndex &) const
void duplicate(Index i)
Duplicate WSV.
Definition: workspace_ng.cc:56
Index nelem() const
Get the number of workspace variables.
Definition: workspace_ng.h:178
Array< WorkspaceVariable > ws
Workspace variable container.
Definition: workspace_ng.h:73
Workspace()
Construct a new workspace.
std::shared_ptr< Workspace > deepcopy()
Gets a full copy that owns all the data (only gets the top of the stack)
std::shared_ptr< WsvMap_type > WsvMap_ptr
Definition: workspace_ng.h:79
Index depth(Index i) const
Return scoping level of the given WSV.
void set_empty(Index i)
Delete WSV.
Definition: workspace_ng.cc:49
std::shared_ptr< void > operator[](Index i)
Retrieve a pointer to the given WSV.
void push_move(Index i, std::shared_ptr< T > &&wsv_ptr)
Move a WSV onto its stack.
Definition: workspace_ng.h:170
This class contains all static information for one workspace variable.
Definition: wsv_aux.h:58
const String & Name() const
Name of this workspace variable.
Definition: wsv_aux.h:92
Helper macros for debugging.
#define ARTS_ASSERT(condition,...)
Definition: debug.h:82
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:134
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
WorkspaceMemoryHandler workspace_memory_handler
The workspace memory handler Defined in workspace_ng.cc.
Definition: workspace_ng.cc:37
const map< String, Index > WsvGroupMap
The map associated with wsv_groups.
Definition: groups.cc:43
#define a
The WorkspaceMemoryHandler.
This file contains the Workspace class.
Auxiliary header stuff related to workspace variable groups.