Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:51:49

0001 #ifndef CONVOL_COEFF_FUNCTION_SERVICE_H
0002 #define CONVOL_COEFF_FUNCTION_SERVICE_H
0003 
0004 /**
0005  * @file ConvolCoeffFunctionService.h
0006  * @author Bryan BERTHOU (SPhN / CEA Saclay)
0007  * @date August 07, 2014
0008  * @version 1.0
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/convol_coeff_function/ConvolCoeffFunctionModule.h"
0023 #include "../ServiceObjectTyped.h"
0024 #include "../utils/VectorUtils.h"
0025 
0026 namespace PARTONS {
0027 class GPDService;
0028 } /* namespace PARTONS */
0029 
0030 namespace PARTONS {
0031 
0032 /**
0033  * @class ConvolCoeffFunctionService
0034  *
0035  * @brief Abstract class for a service to handle and compute pre-configured CCF modules.
0036  */
0037 template<typename KinematicType, typename ResultType> class ConvolCoeffFunctionService: public ServiceObjectTyped<
0038         KinematicType, ResultType> {
0039 
0040 public:
0041 
0042     static const std::string CCF_SERVICE_COMPUTE_SINGLE_KINEMATIC; ///< Name of the XML task used for computing a CCF.
0043     static const std::string CCF_SERVICE_COMPUTE_MANY_KINEMATIC; ///< Name of the XML task used for computing CCFs with a list of kinematics.
0044 
0045     /**
0046      * Destructor.
0047      */
0048     virtual ~ConvolCoeffFunctionService() {
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                             "ccf.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                 ConvolCoeffFunctionService::CCF_SERVICE_COMPUTE_MANY_KINEMATIC)) {
0073             resultList = computeManyKinematicTask(task);
0074         }
0075 
0076         else if (ElemUtils::StringUtils::equals(task.getFunctionName(),
0077                 ConvolCoeffFunctionService::CCF_SERVICE_COMPUTE_SINGLE_KINEMATIC)) {
0078             resultList.add(computeSingleKinematicTask(task));
0079 
0080         }
0081 
0082         else if (!this->computeGeneralTask(task)) {
0083             this->errorUnknownMethod(task);
0084         }
0085 
0086         this->updateResultInfo(resultList, this->m_resultInfo);
0087 
0088         this->m_resultListBuffer = resultList;
0089     }
0090 
0091     /**
0092      * Computes a ConvolCoeffFunctionModule at specific kinematics.
0093      * @param kinematic CCF Kinematics.
0094      * @param pConvolCoeffFunctionModule CCF model to use for the computation.
0095      * @param gpdTypeList List of GPDType to compute. Default: all the GPDTypes available with (both) the ConvolCoeffFunctionModule (AND the underlying GPDModule, if any).
0096      * @return Result.
0097      */
0098     ResultType computeSingleKinematic(const KinematicType &kinematic,
0099             ConvolCoeffFunctionModule<KinematicType, ResultType>* pConvolCoeffFunctionModule,
0100             const List<GPDType>& gpdTypeList = List<GPDType>()) const {
0101 
0102         //get list of GPD types
0103         List<GPDType> restrictedByGPDTypeListFinal = getFinalGPDTypeList(
0104                 pConvolCoeffFunctionModule, gpdTypeList);
0105 
0106         //return
0107         return pConvolCoeffFunctionModule->compute(kinematic,
0108                 restrictedByGPDTypeListFinal);
0109     }
0110 
0111     /**
0112      * Computes a CCF Model for a list of kinematics.
0113      * @param kinematics List of kinematics.
0114      * @param pConvolCoeffFunctionModule CCF model to use for the computation.
0115      * @param gpdTypeList List of GPDType to compute. Default: all the GPDTypes available with (both) the ConvolCoeffFunctionModule (AND the underlying GPDModule, if any).
0116      * @param storeInDB Boolean to store the results and kinematics on the database. Default: false.
0117      * @return List of results.
0118      */
0119     List<ResultType> computeManyKinematic(List<KinematicType> &kinematics,
0120             ConvolCoeffFunctionModule<KinematicType, ResultType>* pConvolCoeffFunctionModule,
0121             const List<GPDType>& gpdTypeList = List<GPDType>()) {
0122 
0123         //debug information
0124         this->debug(__func__,
0125                 ElemUtils::Formatter() << kinematics.size()
0126                         << " CCF kinematic(s) will be computed with "
0127                         << pConvolCoeffFunctionModule->getClassName());
0128 
0129         //initialize
0130         List<ResultType> results;
0131         List<ElemUtils::Packet> listOfPacket;
0132         List<GPDType> finalGPDTypeList = getFinalGPDTypeList(
0133                 pConvolCoeffFunctionModule, gpdTypeList);
0134 
0135         //if to be computed
0136         if (finalGPDTypeList.size() != 0) {
0137 
0138             //init thread
0139             this->initComputationalThread(pConvolCoeffFunctionModule);
0140 
0141             //print info
0142             this->info(__func__, "Thread(s) running ...");
0143 
0144             //batch feature
0145             unsigned int i = 0;
0146             unsigned int j = 0;
0147 
0148             //divide to packets
0149             while (i != kinematics.size()) {
0150 
0151                 listOfPacket.clear();
0152                 j = 0;
0153 
0154                 while ((j != this->m_batchSize) && (i != kinematics.size())) {
0155 
0156                     ElemUtils::Packet packet;
0157                     KinematicType kinematic;
0158                     kinematic = kinematics[i];
0159                     packet << kinematic << finalGPDTypeList;
0160                     listOfPacket.add(packet);
0161                     i++;
0162                     j++;
0163                 }
0164 
0165                 //add, lunch and sort
0166                 this->addTasks(listOfPacket);
0167                 this->launchAllThreadAndWaitingFor();
0168                 this->sortResultList();
0169 
0170                 //print info
0171                 this->info(__func__,
0172                         ElemUtils::Formatter()
0173                                 << "Kinematic(s) already computed: " << i);
0174 
0175                 //update result info
0176                 this->updateResultInfo(this->getResultList(),
0177                         this->m_resultInfo);
0178 
0179                 //add to output
0180                 results.add(this->getResultList());
0181 
0182                 //clear buffer
0183                 this->clearResultListBuffer();
0184             }
0185 
0186             //clear threads
0187             this->clearAllThread();
0188 
0189         } else {
0190             this->info(__func__,
0191                     "Nothing to compute with your computation configuration ; there is no GPDType available");
0192         }
0193 
0194         return results;
0195     }
0196 
0197     /**
0198      * Uses an automation task (XML file) to configure a ConvolCoeffFunctionModule.
0199      * @param task Automation task.
0200      * @return Pre-configured ConvolCoeffFunctionModule.
0201      */
0202     virtual ConvolCoeffFunctionModule<KinematicType, ResultType>* newConvolCoeffFunctionModuleFromTask(
0203             const Task &task) const = 0;
0204 
0205     /**
0206      * Uses an automation task (XML file) to set specific kinematics.
0207      * @param task Task.
0208      * @return CCF kinematics.
0209      */
0210     virtual KinematicType newKinematicFromTask(const Task &task) const = 0;
0211 
0212     /**
0213      * Uses an automation task (XML file) to set a list of kinematics.
0214      * @param task Task.
0215      * @return List of CCF kinematics.
0216      */
0217     virtual List<KinematicType> newListOfKinematicFromTask(
0218             const Task &task) const = 0;
0219 
0220 protected:
0221 
0222     /**
0223      * Default constructor.
0224      */
0225     ConvolCoeffFunctionService(const std::string &className) :
0226             ServiceObjectTyped<KinematicType, ResultType>(className) {
0227     }
0228 
0229 private:
0230 
0231     /**
0232      * Method used in the automated interface to compute CCF.
0233      * @param task Automated XML task.
0234      * @return Result.
0235      */
0236     ResultType computeSingleKinematicTask(Task &task) const {
0237 
0238         //create a kinematic and init it with a list of parameters
0239         KinematicType kinematic = newKinematicFromTask(task);
0240 
0241         //get GPD types
0242         List<GPDType> gpdTypeList = this->getGPDTypeListFromTask(task);
0243 
0244         //get CCF module
0245         ConvolCoeffFunctionModule<KinematicType, ResultType>* pConvolCoeffFunctionModule =
0246                 newConvolCoeffFunctionModuleFromTask(task);
0247 
0248         //make computation
0249         ResultType result = computeSingleKinematic(kinematic,
0250                 pConvolCoeffFunctionModule, gpdTypeList);
0251 
0252         //remove reference to pConvolCoeffFunctionModule pointer.
0253         this->m_pModuleObjectFactory->updateModulePointerReference(
0254                 pConvolCoeffFunctionModule, 0);
0255         pConvolCoeffFunctionModule = 0;
0256 
0257         //return
0258         return result;
0259     }
0260 
0261     /**
0262      * Method used in the automated interface to compute CCFs for a list of kinematics.
0263      * @param task Automated XML task.
0264      * @return List of results.
0265      */
0266     List<ResultType> computeManyKinematicTask(Task& task) {
0267 
0268         //get kinematics
0269         List<KinematicType> listOfKinematic = newListOfKinematicFromTask(task);
0270 
0271         //get GPD types
0272         List<GPDType> gpdTypeList = this->getGPDTypeListFromTask(task);
0273 
0274         //get CCF module
0275         ConvolCoeffFunctionModule<KinematicType, ResultType>* pConvolCoeffFunctionModule =
0276                 newConvolCoeffFunctionModuleFromTask(task);
0277 
0278         //make computation
0279         List<ResultType> results = computeManyKinematic(listOfKinematic,
0280                 pConvolCoeffFunctionModule, gpdTypeList);
0281 
0282         //remove reference to pConvolCoeffFunctionModule pointer
0283         this->m_pModuleObjectFactory->updateModulePointerReference(
0284                 pConvolCoeffFunctionModule, 0);
0285         pConvolCoeffFunctionModule = 0;
0286 
0287         //return
0288         return results;
0289     }
0290 
0291     /**
0292      * Method used to derive an intersection of available GPD types from the various underlying modules.
0293      * @param pConvolCoeffFunctionModule ConvolCoeffFunctionModule used for the computation.
0294      * @param gpdTypeList List of desired GPD types to compute.
0295      * @return List of GPD types.
0296      */
0297     List<GPDType> getFinalGPDTypeList(
0298             ConvolCoeffFunctionModule<KinematicType, ResultType>* pConvolCoeffFunctionModule,
0299             const List<GPDType> &gpdTypeList) const {
0300 
0301         //initialize
0302         List<GPDType> restrictedByGPDTypeListFinal = gpdTypeList;
0303 
0304         //get list of GPD types available
0305         restrictedByGPDTypeListFinal =
0306                 pConvolCoeffFunctionModule->getListOfAvailableGPDTypeForComputation();
0307 
0308         //intersection between available GPDType and GPDType asked
0309         if (!gpdTypeList.isEmpty()) {
0310             restrictedByGPDTypeListFinal = VectorUtils::intersection(
0311                     restrictedByGPDTypeListFinal, gpdTypeList);
0312         }
0313 
0314         //debug info
0315         this->debug(__func__,
0316                 ElemUtils::Formatter() << restrictedByGPDTypeListFinal.size()
0317                         << " GPDType will be computed");
0318 
0319         //return
0320         return restrictedByGPDTypeListFinal;
0321     }
0322 };
0323 
0324 template<typename KinematicType, typename ResultType>
0325 const std::string ConvolCoeffFunctionService<KinematicType, ResultType>::CCF_SERVICE_COMPUTE_SINGLE_KINEMATIC =
0326         "computeSingleKinematic";
0327 
0328 template<typename KinematicType, typename ResultType>
0329 const std::string ConvolCoeffFunctionService<KinematicType, ResultType>::CCF_SERVICE_COMPUTE_MANY_KINEMATIC =
0330         "computeManyKinematic";
0331 
0332 } /* namespace PARTONS */
0333 
0334 #endif /* CONVOL_COEFF_FUNCTION_SERVICE_H */