File indexing completed on 2026-06-02 08:51:49
0001 #ifndef OBSERVABLE_SERVICE_H
0002 #define OBSERVABLE_SERVICE_H
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <ElementaryUtils/logger/CustomException.h>
0012 #include <ElementaryUtils/parameters/GenericType.h>
0013 #include <ElementaryUtils/PropertiesManager.h>
0014 #include <ElementaryUtils/string_utils/Formatter.h>
0015 #include <ElementaryUtils/string_utils/StringUtils.h>
0016 #include <ElementaryUtils/thread/Packet.h>
0017 #include <string>
0018
0019 #include "../beans/automation/Task.h"
0020 #include "../beans/gpd/GPDType.h"
0021 #include "../beans/List.h"
0022 #include "../modules/observable/Observable.h"
0023 #include "../modules/process/ProcessModule.h"
0024 #include "../ServiceObjectTyped.h"
0025 #include "../utils/VectorUtils.h"
0026
0027 namespace PARTONS {
0028
0029
0030
0031
0032
0033
0034 template<typename KinematicType, typename ResultType>
0035 class ObservableService: public ServiceObjectTyped<KinematicType, ResultType> {
0036
0037 public:
0038
0039 static const std::string OBSERVABLE_SERVICE_COMPUTE_SINGLE_KINEMATIC;
0040 static const std::string OBSERVABLE_SERVICE_COMPUTE_MANY_KINEMATIC;
0041
0042
0043
0044
0045 virtual ~ObservableService() {
0046 }
0047
0048
0049
0050
0051 virtual void resolveObjectDependencies() {
0052
0053 ServiceObjectTyped<KinematicType, ResultType>::resolveObjectDependencies();
0054
0055 try {
0056 this->m_batchSize = ElemUtils::GenericType(
0057 ElemUtils::PropertiesManager::getInstance()->getString(
0058 "observable.service.batch.size")).toUInt();
0059 } catch (const std::exception &e) {
0060 throw ElemUtils::CustomException(this->getClassName(), __func__,
0061 e.what());
0062 }
0063 }
0064
0065 virtual void computeTask(Task &task) {
0066
0067 ServiceObjectTyped<KinematicType, ResultType>::computeTask(task);
0068
0069 List<ResultType> resultList;
0070
0071 if (ElemUtils::StringUtils::equals(task.getFunctionName(),
0072 ObservableService::OBSERVABLE_SERVICE_COMPUTE_MANY_KINEMATIC)) {
0073 resultList = computeManyKinematicTask(task);
0074 }
0075
0076 else if (ElemUtils::StringUtils::equals(task.getFunctionName(),
0077 ObservableService::OBSERVABLE_SERVICE_COMPUTE_SINGLE_KINEMATIC)) {
0078 resultList.add(computeSingleKinematicTask(task));
0079 }
0080
0081 else if (!this->computeGeneralTask(task)) {
0082 this->errorUnknownMethod(task);
0083 }
0084
0085 this->updateResultInfo(resultList, this->m_resultInfo);
0086
0087 this->m_resultListBuffer = resultList;
0088 }
0089
0090
0091
0092
0093
0094
0095
0096
0097 ResultType computeSingleKinematic(const KinematicType &observableKinematic,
0098 Observable<KinematicType, ResultType>* pObservable,
0099 const List<GPDType> & gpdTypeList = List<GPDType>()) const {
0100
0101
0102 List<GPDType> restrictedByGPDTypeListFinal = getFinalGPDTypeList(
0103 pObservable, gpdTypeList);
0104
0105
0106 return pObservable->compute(observableKinematic, gpdTypeList);
0107 }
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 List<ResultType> computeManyKinematic(
0118 const List<KinematicType> & listOfKinematic,
0119 Observable<KinematicType, ResultType>* pObservable,
0120 const List<GPDType>& gpdTypeList = List<GPDType>()) {
0121
0122
0123 this->debug(__func__,
0124 ElemUtils::Formatter() << listOfKinematic.size()
0125 << " Observable kinematic(s) will be computed with "
0126 << pObservable->getClassName());
0127
0128
0129 List<ResultType> results;
0130 List<ElemUtils::Packet> listOfPacket;
0131 List<GPDType> finalListOfGPDType = getFinalGPDTypeList(pObservable,
0132 gpdTypeList);
0133
0134
0135 if (finalListOfGPDType.size() != 0) {
0136
0137
0138 this->initComputationalThread(pObservable);
0139
0140
0141 this->info(__func__, "Thread(s) running ...");
0142
0143
0144 unsigned int i = 0;
0145 unsigned int j = 0;
0146
0147
0148 while (i != listOfKinematic.size()) {
0149
0150 listOfPacket.clear();
0151 j = 0;
0152
0153 while ((j != this->m_batchSize) && (i != listOfKinematic.size())) {
0154
0155 ElemUtils::Packet packet;
0156 KinematicType kinematic;
0157 kinematic = listOfKinematic[i];
0158 packet << kinematic << finalListOfGPDType;
0159 listOfPacket.add(packet);
0160 i++;
0161 j++;
0162 }
0163
0164
0165 this->addTasks(listOfPacket);
0166 this->launchAllThreadAndWaitingFor();
0167 this->sortResultList();
0168
0169
0170 this->info(__func__,
0171 ElemUtils::Formatter()
0172 << "Kinematic(s) already computed: " << i);
0173
0174
0175 this->updateResultInfo(this->getResultList(),
0176 this->m_resultInfo);
0177
0178
0179 results.add(this->getResultList());
0180
0181
0182 this->clearResultListBuffer();
0183 }
0184
0185
0186 this->clearAllThread();
0187
0188 } else {
0189 this->info(__func__,
0190 "Nothing to compute with your computation configuration ; there is no GPDType available");
0191 }
0192
0193 return results;
0194 }
0195
0196
0197
0198
0199
0200
0201 virtual ProcessModule<KinematicType, ResultType>* newProcessModuleFromTask(
0202 const Task &task) const = 0;
0203
0204
0205
0206
0207
0208
0209 virtual Observable<KinematicType, ResultType>* newObservableModuleFromTask(
0210 const Task &task) const = 0;
0211
0212
0213
0214
0215
0216
0217 virtual KinematicType newKinematicFromTask(const Task &task) const = 0;
0218
0219
0220
0221
0222
0223
0224 virtual List<KinematicType> newListOfKinematicFromTask(
0225 const Task &task) const = 0;
0226
0227 protected:
0228
0229
0230
0231
0232 ObservableService(const std::string &className) :
0233 ServiceObjectTyped<KinematicType, ResultType>(className) {
0234 }
0235
0236 private:
0237
0238
0239
0240
0241
0242
0243 ResultType computeSingleKinematicTask(Task &task) {
0244
0245
0246 KinematicType kinematic = newKinematicFromTask(task);
0247
0248
0249 List<GPDType> gpdTypeList = this->getGPDTypeListFromTask(task);
0250
0251
0252 Observable<KinematicType, ResultType>* pObservable =
0253 newObservableModuleFromTask(task);
0254
0255
0256 ResultType result = computeSingleKinematic(kinematic, pObservable,
0257 gpdTypeList);
0258
0259
0260 this->m_pModuleObjectFactory->updateModulePointerReference(pObservable,
0261 0);
0262 pObservable = 0;
0263
0264 return result;
0265 }
0266
0267
0268
0269
0270
0271
0272 List<ResultType> computeManyKinematicTask(Task &task) {
0273
0274
0275 List<KinematicType> listOfKinematic = newListOfKinematicFromTask(task);
0276
0277
0278 List<GPDType> gpdTypeList = this->getGPDTypeListFromTask(task);
0279
0280
0281 Observable<KinematicType, ResultType>* pObservable =
0282 newObservableModuleFromTask(task);
0283
0284
0285 List<ResultType> results = computeManyKinematic(listOfKinematic,
0286 pObservable, gpdTypeList);
0287
0288
0289 this->m_pModuleObjectFactory->updateModulePointerReference(pObservable,
0290 0);
0291 pObservable = 0;
0292
0293
0294 return results;
0295 }
0296
0297
0298
0299
0300
0301
0302
0303 List<GPDType> getFinalGPDTypeList(
0304 Observable<KinematicType, ResultType>* pObservable,
0305 const List<GPDType> &gpdTypeList) const {
0306
0307
0308 List<GPDType> restrictedByGPDTypeListFinal = gpdTypeList;
0309
0310
0311 restrictedByGPDTypeListFinal =
0312 pObservable->getListOfAvailableGPDTypeForComputation();
0313
0314
0315 if (!gpdTypeList.isEmpty()) {
0316 restrictedByGPDTypeListFinal = VectorUtils::intersection(
0317 restrictedByGPDTypeListFinal, gpdTypeList);
0318 }
0319
0320
0321 this->debug(__func__,
0322 ElemUtils::Formatter() << restrictedByGPDTypeListFinal.size()
0323 << " GPDType will be computed");
0324
0325
0326 return restrictedByGPDTypeListFinal;
0327 }
0328 };
0329
0330 template<typename KinematicType, typename ResultType>
0331 const std::string ObservableService<KinematicType, ResultType>::OBSERVABLE_SERVICE_COMPUTE_SINGLE_KINEMATIC =
0332 "computeSingleKinematic";
0333
0334 template<typename KinematicType, typename ResultType>
0335 const std::string ObservableService<KinematicType, ResultType>::OBSERVABLE_SERVICE_COMPUTE_MANY_KINEMATIC =
0336 "computeManyKinematic";
0337
0338 }
0339
0340 #endif