|
12 | 12 | #include "Framework/AODReaderHelpers.h" |
13 | 13 | #include "Framework/AnalysisHelpers.h" |
14 | 14 | #include "Framework/AnalysisDataModelHelpers.h" |
15 | | -#include "Framework/DataProcessingHelpers.h" |
16 | 15 | #include "Framework/ExpressionHelpers.h" |
| 16 | +#include "Framework/DataProcessingHelpers.h" |
17 | 17 | #include "Framework/AlgorithmSpec.h" |
18 | 18 | #include "Framework/ControlService.h" |
19 | 19 | #include "Framework/CallbackService.h" |
20 | 20 | #include "Framework/EndOfStreamContext.h" |
21 | 21 | #include "Framework/DataSpecUtils.h" |
22 | | -#include "Framework/ExpressionJSONHelpers.h" |
| 22 | +#include "ExpressionJSONHelpers.h" |
| 23 | +#include "Framework/ConfigContext.h" |
| 24 | +#include "Framework/AnalysisContext.h" |
23 | 25 |
|
24 | 26 | #include <Monitoring/Monitoring.h> |
25 | 27 |
|
@@ -136,72 +138,141 @@ auto make_spawn(InputSpec const& input, ProcessingContext& pc) |
136 | 138 | return o2::framework::spawner<D>(extractOriginals<sources.size(), sources>(pc), input.binding.c_str(), projectors.data(), projector, schema); |
137 | 139 | } |
138 | 140 |
|
139 | | -struct Spawnable { |
140 | | - std::vector<expressions::Projector> projectors; |
| 141 | +struct Maker |
| 142 | +{ |
| 143 | + std::string binding; |
141 | 144 | std::vector<std::string> labels; |
| 145 | + std::vector<std::shared_ptr<gandiva::Expression>> expressions; |
| 146 | + std::shared_ptr<gandiva::Projector> projector = nullptr; |
142 | 147 | std::shared_ptr<arrow::Schema> schema; |
143 | 148 |
|
| 149 | + header::DataOrigin origin; |
| 150 | + header::DataDescription description; |
| 151 | + header::DataHeader::SubSpecificationType version; |
| 152 | + |
| 153 | + std::shared_ptr<arrow::Table> make(ProcessingContext& pc) |
| 154 | + { |
| 155 | + std::vector<std::shared_ptr<arrow::Table>> originals; |
| 156 | + for (auto const& label : labels) { |
| 157 | + originals.push_back(pc.inputs().get<TableConsumer>(label)->asArrowTable()); |
| 158 | + } |
| 159 | + auto fullTable = soa::ArrowHelpers::joinTables(std::move(originals), std::span{labels.begin(), labels.size()}); |
| 160 | + if (projector == nullptr) { |
| 161 | + auto s = gandiva::Projector::Make( |
| 162 | + fullTable->schema(), |
| 163 | + expressions, |
| 164 | + &projector); |
| 165 | + if (!s.ok()) { |
| 166 | + throw o2::framework::runtime_error_f("Failed to create projector: %s", s.ToString().c_str()); |
| 167 | + } |
| 168 | + } |
| 169 | + |
| 170 | + return spawnerHelper(fullTable, schema, binding.c_str(), schema->num_fields(), projector); |
| 171 | + } |
| 172 | + |
| 173 | +}; |
| 174 | + |
| 175 | +struct Spawnable { |
| 176 | + std::string binding; |
| 177 | + std::vector<std::string> labels; |
| 178 | + std::vector<expressions::Projector> projectors; |
| 179 | + std::vector<std::shared_ptr<gandiva::Expression>> expressions; |
| 180 | + std::shared_ptr<arrow::Schema> outputSchema; |
| 181 | + std::shared_ptr<arrow::Schema> inputSchema; |
| 182 | + |
| 183 | + header::DataOrigin origin; |
| 184 | + header::DataDescription description; |
| 185 | + header::DataHeader::SubSpecificationType version; |
| 186 | + |
144 | 187 | Spawnable(InputSpec const& spec) |
| 188 | + : binding{spec.binding} |
145 | 189 | { |
146 | | - auto loc = std::find_if(spec.metadata.begin(), spec.metadata.end(), [](ConfigParamSpec const& spc){ return spc.name.compare("projectors") == 0; }); |
| 190 | + auto&& [origin_, description_, version_] = DataSpecUtils::asConcreteDataMatcher(spec); |
| 191 | + origin = origin_; |
| 192 | + description = description_; |
| 193 | + version = version_; |
| 194 | + auto loc = std::find_if(spec.metadata.begin(), spec.metadata.end(), [](ConfigParamSpec const& cps){ return cps.name.compare("projectors") == 0; }); |
147 | 195 | std::stringstream iws(loc->defaultValue.get<std::string>()); |
148 | 196 | projectors = ExpressionJSONHelpers::read(iws); |
| 197 | + |
| 198 | + loc = std::find_if(spec.metadata.begin(), spec.metadata.end(), [](ConfigParamSpec const& cps){ return cps.name.compare("schema") == 0; }); |
| 199 | + iws.clear(); |
| 200 | + iws.str(loc->defaultValue.get<std::string>()); |
| 201 | + outputSchema = ArrowJSONHelpers::read(iws); |
| 202 | + |
149 | 203 | for (auto& i : spec.metadata) { |
150 | 204 | if (i.name.starts_with("input:")) { |
151 | 205 | labels.emplace_back(i.name.substr(6)); |
152 | 206 | } |
153 | 207 | } |
| 208 | + |
| 209 | + std::vector<std::shared_ptr<arrow::Field>> fields; |
| 210 | + for (auto& p : projectors) { |
| 211 | + expressions::walk(p.node.get(), |
| 212 | + [&fields](expressions::Node* n) mutable { |
| 213 | + if (n->self.index() == 1) { |
| 214 | + auto& b = std::get<expressions::BindingNode>(n->self); |
| 215 | + if ( std::find_if(fields.begin(), fields.end(), [&b](std::shared_ptr<arrow::Field> const& field){ return field->name() == b.name; }) == fields.end() ) { |
| 216 | + fields.emplace_back(std::make_shared<arrow::Field>(b.name, expressions::concreteArrowType(b.type))); |
| 217 | + } |
| 218 | + } |
| 219 | + }); |
| 220 | + } |
| 221 | + inputSchema = std::make_shared<arrow::Schema>(fields); |
| 222 | + |
| 223 | + int i = 0; |
| 224 | + for (auto& p : projectors) { |
| 225 | + expressions.push_back( |
| 226 | + expressions::makeExpression( |
| 227 | + expressions::createExpressionTree( |
| 228 | + expressions::createOperations(p), |
| 229 | + inputSchema), |
| 230 | + outputSchema->field(i)) |
| 231 | + ); |
| 232 | + ++i; |
| 233 | + } |
| 234 | + } |
| 235 | + |
| 236 | + std::shared_ptr<gandiva::Projector> makeProjector() |
| 237 | + { |
| 238 | + return expressions::createProjectorHelper(projectors.size(), projectors.data(), inputSchema, outputSchema->fields()); |
| 239 | + } |
| 240 | + |
| 241 | + Maker createMaker() |
| 242 | + { |
| 243 | + return { |
| 244 | + binding, |
| 245 | + labels, |
| 246 | + expressions, |
| 247 | + nullptr, |
| 248 | + outputSchema, |
| 249 | + origin, |
| 250 | + description, |
| 251 | + version |
| 252 | + }; |
154 | 253 | } |
| 254 | + |
155 | 255 | }; |
| 256 | + |
156 | 257 | } // namespace |
157 | 258 |
|
158 | | -AlgorithmSpec AODReaderHelpers::aodSpawnerCallback(std::vector<InputSpec>& requested) |
| 259 | +AlgorithmSpec AODReaderHelpers::aodSpawnerCallback(/*std::vector<InputSpec>& requested*/ ConfigContext const& ctx) |
159 | 260 | { |
160 | | - return AlgorithmSpec::InitCallback{[requested](InitContext& /*ic*/) { |
| 261 | + auto& ac = ctx.services().get<AnalysisContext>(); |
| 262 | + return AlgorithmSpec::InitCallback{[requested = ac.spawnerInputs](InitContext& /*ic*/) { |
161 | 263 | std::vector<Spawnable> spawnables; |
| 264 | + for (auto& i : requested) { |
| 265 | + spawnables.emplace_back(i); |
| 266 | + } |
| 267 | + std::vector<Maker> makers; |
| 268 | + for (auto& s : spawnables) { |
| 269 | + makers.push_back(s.createMaker()); |
| 270 | + } |
162 | 271 |
|
163 | | - return [requested, spawnables](ProcessingContext& pc) { |
| 272 | + return [makers](ProcessingContext& pc) mutable { |
164 | 273 | auto outputs = pc.outputs(); |
165 | | - // spawn tables |
166 | | - for (auto& input : requested) { |
167 | | - auto&& [origin, description, version] = DataSpecUtils::asConcreteDataMatcher(input); |
168 | | - if (description == header::DataDescription{"EXTRACK"}) { |
169 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXTRACK/0"_h>>(input, pc)); |
170 | | - } else if (description == header::DataDescription{"EXTRACK_IU"}) { |
171 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXTRACK_IU/0"_h>>(input, pc)); |
172 | | - } else if (description == header::DataDescription{"EXTRACKCOV"}) { |
173 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXTRACKCOV/0"_h>>(input, pc)); |
174 | | - } else if (description == header::DataDescription{"EXTRACKCOV_IU"}) { |
175 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXTRACKCOV_IU/0"_h>>(input, pc)); |
176 | | - } else if (description == header::DataDescription{"EXTRACKEXTRA"}) { |
177 | | - if (version == 0U) { |
178 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXTRACKEXTRA/0"_h>>(input, pc)); |
179 | | - } else if (version == 1U) { |
180 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXTRACKEXTRA/1"_h>>(input, pc)); |
181 | | - } else if (version == 2U) { |
182 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXTRACKEXTRA/2"_h>>(input, pc)); |
183 | | - } |
184 | | - } else if (description == header::DataDescription{"EXMFTTRACK"}) { |
185 | | - if (version == 0U) { |
186 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXMFTTRACK/0"_h>>(input, pc)); |
187 | | - } else if (version == 1U) { |
188 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXMFTTRACK/1"_h>>(input, pc)); |
189 | | - } |
190 | | - } else if (description == header::DataDescription{"EXMFTTRACKCOV"}) { |
191 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXMFTTRACKCOV/0"_h>>(input, pc)); |
192 | | - } else if (description == header::DataDescription{"EXFWDTRACK"}) { |
193 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXFWDTRACK/0"_h>>(input, pc)); |
194 | | - } else if (description == header::DataDescription{"EXFWDTRACKCOV"}) { |
195 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXFWDTRACKCOV/0"_h>>(input, pc)); |
196 | | - } else if (description == header::DataDescription{"EXMCPARTICLE"}) { |
197 | | - if (version == 0U) { |
198 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXMCPARTICLE/0"_h>>(input, pc)); |
199 | | - } else if (version == 1U) { |
200 | | - outputs.adopt(Output{origin, description, version}, make_spawn<o2::aod::Hash<"EXMCPARTICLE/1"_h>>(input, pc)); |
201 | | - } |
202 | | - } else { |
203 | | - throw runtime_error("Not an extended table"); |
204 | | - } |
| 274 | + for (auto& maker : makers) { |
| 275 | + outputs.adopt(Output{maker.origin, maker.description, maker.version}, maker.make(pc)); |
205 | 276 | } |
206 | 277 | }; |
207 | 278 | }}; |
|
0 commit comments