CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/RecoJets/FFTJetProducers/src/FFTJetParameterParser.cc

Go to the documentation of this file.
00001 #include <cstdlib>
00002 #include <cstring>
00003 #include <string>
00004 #include <fstream>
00005 
00006 #include "RecoJets/FFTJetProducers/interface/FFTJetParameterParser.h"
00007 
00008 #include "RecoJets/FFTJetAlgorithms/interface/JetConvergenceDistance.h"
00009 #include "RecoJets/FFTJetAlgorithms/interface/ScaleCalculators.h"
00010 #include "RecoJets/FFTJetAlgorithms/interface/EtaAndPtDependentPeakSelector.h"
00011 
00012 #include "FWCore/Utilities/interface/Exception.h"
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 
00015 #include "fftjet/PeakSelectors.hh"
00016 #include "fftjet/Kernel2dFactory.hh"
00017 #include "fftjet/GaussianNoiseMembershipFcn.hh"
00018 #include "fftjet/EquidistantSequence.hh"
00019 #include "fftjet/PeakEtaPhiDistance.hh"
00020 #include "fftjet/PeakEtaDependentDistance.hh"
00021 #include "fftjet/JetProperty.hh"
00022 #include "fftjet/InterpolatedMembershipFcn.hh"
00023 #include "fftjet/CompositeKernel.hh"
00024 #include "fftjet/InterpolatedKernel.hh"
00025 #include "fftjet/InterpolatedKernel3d.hh"
00026 #include "fftjet/MagneticSmearingKernel.hh"
00027 
00028 #define make_param(type, varname) const \
00029     type & varname (ps.getParameter< type >( #varname ))
00030 
00031 using namespace fftjetcms;
00032 
00033 typedef fftjet::RecombinedJet<VectorLike> RecoFFTJet;
00034 
00035 static bool parse_peak_member_function(const char* fname,
00036     fftjet::JetProperty<fftjet::Peak>::JetMemberFunction *f)
00037 {
00038     if (strcmp(fname, "eta") == 0)
00039         *f = &fftjet::Peak::eta;
00040     else if (strcmp(fname, "phi") == 0)
00041         *f = &fftjet::Peak::phi;
00042     else if (strcmp(fname, "magnitude") == 0)
00043         *f = &fftjet::Peak::magnitude;
00044     else if (strcmp(fname, "driftSpeed") == 0)
00045         *f = &fftjet::Peak::driftSpeed;
00046     else if (strcmp(fname, "magSpeed") == 0)
00047         *f = &fftjet::Peak::magSpeed;
00048     else if (strcmp(fname, "lifetime") == 0)
00049         *f = &fftjet::Peak::lifetime;
00050     else if (strcmp(fname, "scale") == 0)
00051         *f = &fftjet::Peak::scale;
00052     else if (strcmp(fname, "nearestNeighborDistance") == 0)
00053         *f = &fftjet::Peak::nearestNeighborDistance;
00054     else if (strcmp(fname, "membershipFactor") == 0)
00055         *f = &fftjet::Peak::membershipFactor;
00056     else if (strcmp(fname, "recoScale") == 0)
00057         *f = &fftjet::Peak::recoScale;
00058     else if (strcmp(fname, "recoScaleRatio") == 0)
00059         *f = &fftjet::Peak::recoScaleRatio;
00060     else if (strcmp(fname, "laplacian") == 0)
00061         *f = &fftjet::Peak::laplacian;
00062     else if (strcmp(fname, "hessianDeterminant") == 0)
00063         *f = &fftjet::Peak::hessianDeterminant;
00064     else if (strcmp(fname, "clusterRadius") == 0)
00065         *f = &fftjet::Peak::clusterRadius;
00066     else if (strcmp(fname, "clusterSeparation") == 0)
00067         *f = &fftjet::Peak::clusterSeparation;
00068     else
00069     {
00070         return false;
00071     }
00072     return true;
00073 }
00074 
00075 static bool parse_jet_member_function(const char* fname,
00076     fftjet::JetProperty<RecoFFTJet>::JetMemberFunction *f)
00077 {
00078     if (strcmp(fname, "peakEta") == 0)
00079         *f = &RecoFFTJet::peakEta;
00080     else if (strcmp(fname, "peakPhi") == 0)
00081         *f = &RecoFFTJet::peakPhi;
00082     else if (strcmp(fname, "peakMagnitude") == 0)
00083         *f = &RecoFFTJet::peakMagnitude;
00084     else if (strcmp(fname, "magnitude") == 0)
00085         *f = &RecoFFTJet::magnitude;
00086     else if (strcmp(fname, "driftSpeed") == 0)
00087         *f = &RecoFFTJet::driftSpeed;
00088     else if (strcmp(fname, "magSpeed") == 0)
00089         *f = &RecoFFTJet::magSpeed;
00090     else if (strcmp(fname, "lifetime") == 0)
00091         *f = &RecoFFTJet::lifetime;
00092     else if (strcmp(fname, "scale") == 0)
00093         *f = &RecoFFTJet::scale;
00094     else if (strcmp(fname, "nearestNeighborDistance") == 0)
00095         *f = &RecoFFTJet::nearestNeighborDistance;
00096     else if (strcmp(fname, "membershipFactor") == 0)
00097         *f = &RecoFFTJet::membershipFactor;
00098     else if (strcmp(fname, "recoScale") == 0)
00099         *f = &RecoFFTJet::recoScale;
00100     else if (strcmp(fname, "recoScaleRatio") == 0)
00101         *f = &RecoFFTJet::recoScaleRatio;
00102     else if (strcmp(fname, "laplacian") == 0)
00103         *f = &RecoFFTJet::laplacian;
00104     else if (strcmp(fname, "hessianDeterminant") == 0)
00105         *f = &RecoFFTJet::hessianDeterminant;
00106     else if (strcmp(fname, "clusterRadius") == 0)
00107         *f = &RecoFFTJet::clusterRadius;
00108     else if (strcmp(fname, "clusterSeparation") == 0)
00109         *f = &RecoFFTJet::clusterSeparation;
00110     else
00111     {
00112         return false;
00113     }
00114     return true;
00115 }
00116 
00117 
00118 namespace fftjetcms {
00119 
00120 std::auto_ptr<fftjet::Grid2d<Real> >
00121 fftjet_Grid2d_parser(const edm::ParameterSet& ps)
00122 {
00123     typedef std::auto_ptr<fftjet::Grid2d<Real> > return_type;
00124 
00125     const unsigned nEtaBins = ps.getParameter<unsigned>("nEtaBins");
00126     const Real etaMin = ps.getParameter<Real>("etaMin");
00127     const Real etaMax = ps.getParameter<Real>("etaMax");
00128     const unsigned nPhiBins = ps.getParameter<unsigned>("nPhiBins");
00129     const Real phiBin0Edge = ps.getParameter<Real>("phiBin0Edge");
00130     const std::string title = ps.getUntrackedParameter<std::string>(
00131         "title","");
00132 
00133     if (nEtaBins == 0 || nPhiBins == 0 || etaMin >= etaMax)
00134         return return_type(NULL);
00135 
00136     return return_type(new fftjet::Grid2d<Real>(
00137         nEtaBins,
00138         etaMin,
00139         etaMax,
00140         nPhiBins,
00141         phiBin0Edge,
00142         title.c_str()
00143     ));
00144 }
00145 
00146 
00147 std::auto_ptr<fftjet::Functor1<bool,fftjet::Peak> >
00148 fftjet_PeakSelector_parser(const edm::ParameterSet& ps)
00149 {
00150     typedef std::auto_ptr<fftjet::Functor1<bool,fftjet::Peak> > return_type;
00151 
00152     const std::string peakselector_type = ps.getParameter<std::string>(
00153         "Class");
00154 
00155     if (!peakselector_type.compare("AllPeaksPass"))
00156     {
00157         return return_type(new fftjet::AllPeaksPass());
00158     }
00159 
00160     if (!peakselector_type.compare("EtaAndPtDependentPeakSelector"))
00161     {
00162         const std::string file = ps.getParameter<std::string>("file");
00163         std::ifstream in(file.c_str(),
00164                          std::ios_base::in | std::ios_base::binary);
00165         if (!in.is_open())
00166             throw cms::Exception("FFTJetBadConfig")
00167                 << "Failed to open file " << file << std::endl;
00168         EtaAndPtDependentPeakSelector* ptr =
00169             new EtaAndPtDependentPeakSelector(in);
00170         if (!ptr->isValid())
00171             throw cms::Exception("FFTJetBadConfig")
00172                 << "Failed to read file " << file << std::endl;
00173         return return_type(ptr);
00174     }
00175 
00176     if (!peakselector_type.compare("EtaAndPtLookupPeakSelector"))
00177     {
00178         make_param(unsigned, nx);
00179         make_param(unsigned, ny);
00180         make_param(double, xmin);
00181         make_param(double, xmax);
00182         make_param(double, ymin);
00183         make_param(double, ymax);
00184         make_param(std::vector<double>, data);
00185 
00186         if (xmin >= xmax || ymin >= ymax || !nx || !ny || data.size() != nx*ny)
00187             throw cms::Exception("FFTJetBadConfig")
00188                 << "Failed to configure EtaAndPtLookupPeakSelector" << std::endl;
00189 
00190         return return_type(new EtaAndPtLookupPeakSelector(
00191                                nx, xmin, xmax, ny, ymin, ymax, data));
00192     }
00193 
00194     if (!peakselector_type.compare("SimplePeakSelector"))
00195     {
00196         const double magCut = ps.getParameter<double>("magCut");
00197         const double driftSpeedCut = ps.getParameter<double>("driftSpeedCut");
00198         const double magSpeedCut = ps.getParameter<double>("magSpeedCut");
00199         const double lifeTimeCut = ps.getParameter<double>("lifeTimeCut");
00200         const double NNDCut = ps.getParameter<double>("NNDCut");
00201         const double etaCut = ps.getParameter<double>("etaCut");
00202 
00203         return return_type(new fftjet::SimplePeakSelector(
00204             magCut, driftSpeedCut ,magSpeedCut, lifeTimeCut, NNDCut, etaCut));
00205     }
00206 
00207     if (!peakselector_type.compare("ScalePowerPeakSelector"))
00208     {
00209         const double a = ps.getParameter<double>("a");
00210         const double p = ps.getParameter<double>("p");
00211         const double b = ps.getParameter<double>("b");
00212         const double etaCut = ps.getParameter<double>("etaCut");
00213 
00214         return return_type(new fftjet::ScalePowerPeakSelector(
00215                                a, p, b, etaCut));
00216     }
00217 
00218     return return_type(NULL);
00219 }
00220 
00221 
00222 std::auto_ptr<fftjet::ScaleSpaceKernel>
00223 fftjet_MembershipFunction_parser(const edm::ParameterSet& ps)
00224 {
00225     typedef std::auto_ptr<fftjet::ScaleSpaceKernel> return_type;
00226 
00227     const std::string MembershipFunction_type = ps.getParameter<std::string>(
00228         "Class");
00229 
00230     // Parse special cases first
00231     if (!MembershipFunction_type.compare("InterpolatedMembershipFcn"))
00232     {
00233         // This is a kernel defined by a 4d (sparsified) lookup table.
00234         // Here, it is simply loaded from a file using a built-in
00235         // method from fftjet. Note that the table representation
00236         // must be native binary (this will not work on platforms with
00237         // different endianity of floating point standard).
00238         const std::string file = ps.getParameter<std::string>("file");
00239         std::ifstream in(file.c_str(),
00240                          std::ios_base::in | std::ios_base::binary);
00241         if (!in.is_open())
00242             throw cms::Exception("FFTJetBadConfig")
00243                 << "Failed to open file " << file << std::endl;
00244         return return_type(fftjet::InterpolatedMembershipFcn<float>::read(in));
00245     }
00246 
00247     if (!MembershipFunction_type.compare("Composite"))
00248     {
00249         throw cms::Exception("FFTJetBadConfig")
00250             << "Parsing of CompositeKernel objects is not implemented yet"
00251             << std::endl;
00252     }
00253 
00254     if (!MembershipFunction_type.compare("MagneticSmearing"))
00255     {
00256         // This kernel represents smearing of a jet in phi
00257         // in a magnetic field. The meaning of the parameters
00258         // is explained in the comments in the MagneticSmearingKernel.hh
00259         // header file of the fftjet package.
00260         make_param(std::vector<double>, fragmentationData);
00261         make_param(double, numeratorConst);
00262         make_param(double, charge1Fraction);
00263         make_param(double, charge2Fraction);
00264         make_param(unsigned, samplesPerBin);
00265 
00266         if (fragmentationData.empty())
00267             throw cms::Exception("FFTJetBadConfig")
00268                 << "Fragmentation function data not defined for "
00269                 "MagneticSmearingKernel" << std::endl;
00270         if (samplesPerBin < 1U)
00271             throw cms::Exception("FFTJetBadConfig")
00272                 << "Bad number of samples per bin in "
00273                 "MagneticSmearingKernel" << std::endl;
00274 
00275         fftjet::LinearInterpolator1d* fragmentationFunction = 
00276             new fftjet::LinearInterpolator1d(
00277                 &fragmentationData[0], fragmentationData.size(), 0.0, 1.0);
00278 
00279         return return_type(
00280             new fftjet::MagneticSmearingKernel<fftjet::LinearInterpolator1d>(
00281                 fragmentationFunction, numeratorConst,
00282                 charge1Fraction, charge2Fraction,
00283                 samplesPerBin, true));
00284     }
00285 
00286     if (!MembershipFunction_type.compare("Interpolated"))
00287     {
00288         // This is a kernel defined by a histogram-like 2d lookup table
00289         make_param(double, sx);
00290         make_param(double, sy);
00291         make_param(int, scalePower);
00292         make_param(unsigned, nxbins);
00293         make_param(double, xmin);
00294         make_param(double, xmax);
00295         make_param(unsigned, nybins);
00296         make_param(double, ymin);
00297         make_param(double, ymax);
00298         make_param(std::vector<double>, data);
00299 
00300         if (data.size() != nxbins*nybins)
00301             throw cms::Exception("FFTJetBadConfig")
00302                 << "Bad number of data points for Interpolated kernel"
00303                 << std::endl;
00304 
00305         return return_type(new fftjet::InterpolatedKernel(
00306                                sx, sy, scalePower,
00307                                &data[0], nxbins, xmin, xmax,
00308                                nybins, ymin, ymax));
00309     }
00310 
00311     if (!MembershipFunction_type.compare("Interpolated3d"))
00312     {
00313         // This is a kernel defined by a histogram-like 3d lookup table
00314         make_param(std::vector<double>, data);
00315         make_param(std::vector<double>, scales);
00316         make_param(bool, useLogSpaceForScale);
00317         make_param(unsigned, nxbins);
00318         make_param(double, xmin);
00319         make_param(double, xmax);
00320         make_param(unsigned, nybins);
00321         make_param(double, ymin);
00322         make_param(double, ymax);
00323 
00324         if (data.size() != nxbins*nybins*scales.size())
00325             throw cms::Exception("FFTJetBadConfig")
00326                 << "Bad number of data points for Interpolated3d kernel"
00327                 << std::endl;
00328 
00329         return return_type(new fftjet::InterpolatedKernel3d(
00330                                &data[0], scales, useLogSpaceForScale,
00331                                nxbins, xmin, xmax, nybins, ymin, ymax));
00332     }
00333 
00334     // This is not a special kernel. Try one of the classes
00335     // in the kernel factory provided by FFTJet.
00336     fftjet::DefaultKernel2dFactory factory;
00337     if (factory[MembershipFunction_type] == NULL) {
00338         return return_type(NULL);
00339     }
00340 
00341     make_param(double, sx);
00342     make_param(double, sy);
00343     make_param(int, scalePower);
00344     make_param(std::vector<double>, kernelParameters);
00345 
00346     const int n_expected = factory[MembershipFunction_type]->nParameters();
00347     if (n_expected >= 0)
00348         if (static_cast<unsigned>(n_expected) != kernelParameters.size())
00349             throw cms::Exception("FFTJetBadConfig")
00350                 << "Bad number of kernel parameters" << std::endl;
00351 
00352     return std::auto_ptr<fftjet::ScaleSpaceKernel>(
00353         factory[MembershipFunction_type]->create(
00354             sx, sy, scalePower, kernelParameters));
00355 }
00356 
00357 
00358 std::auto_ptr<AbsBgFunctor>
00359 fftjet_BgFunctor_parser(const edm::ParameterSet& ps)
00360 {
00361     const std::string bg_Membership_type = ps.getParameter<std::string>(
00362         "Class");
00363 
00364     if (!bg_Membership_type.compare("GaussianNoiseMembershipFcn"))
00365     {
00366         const double minWeight = ps.getParameter<double>("minWeight");
00367         const double prior = ps.getParameter<double>("prior");
00368         return std::auto_ptr<AbsBgFunctor>(
00369             new fftjet::GaussianNoiseMembershipFcn(minWeight,prior));
00370     }
00371 
00372     return std::auto_ptr<AbsBgFunctor>(NULL);
00373 }
00374 
00375 
00376 std::auto_ptr<std::vector<double> >
00377 fftjet_ScaleSet_parser(const edm::ParameterSet& ps)
00378 {
00379     typedef std::auto_ptr<std::vector<double> > return_type;
00380 
00381     const std::string className = ps.getParameter<std::string>("Class");
00382 
00383     if (!className.compare("EquidistantInLinearSpace") ||
00384         !className.compare("EquidistantInLogSpace"))
00385     {
00386         const double minScale = ps.getParameter<double>("minScale");
00387         const double maxScale = ps.getParameter<double>("maxScale");
00388         const unsigned nScales = ps.getParameter<unsigned>("nScales");
00389 
00390         if (minScale <= 0.0 || maxScale <= 0.0 ||
00391             nScales == 0 || minScale == maxScale)
00392             return return_type(NULL);
00393 
00394         // Can't return pointers to EquidistantInLinearSpace
00395         // or EquidistantInLogSpace directly because std::vector
00396         // destructor is not virtual.
00397         if (!className.compare("EquidistantInLinearSpace"))
00398             return return_type(new std::vector<double>(
00399                                    fftjet::EquidistantInLinearSpace(
00400                                        minScale, maxScale, nScales)));
00401         else
00402             return return_type(new std::vector<double>(
00403                                    fftjet::EquidistantInLogSpace(
00404                                        minScale, maxScale, nScales)));
00405     }
00406 
00407     if (!className.compare("UserSet"))
00408     {
00409         return_type scales(new std::vector<double>(
00410             ps.getParameter<std::vector<double> >("scales")));
00411 
00412         // Verify that all scales are positive and unique
00413         const unsigned nscales = scales->size();
00414         for (unsigned i=0; i<nscales; ++i)
00415             if ((*scales)[i] <= 0.0)
00416                 return return_type(NULL);
00417 
00418         for (unsigned i=1; i<nscales; ++i)
00419             for (unsigned j=0; j<i; ++j)
00420                 if ((*scales)[i] == (*scales)[j])
00421                     return return_type(NULL);
00422 
00423         return scales;
00424     }
00425 
00426     return return_type(NULL);
00427 }
00428 
00429 
00430 std::auto_ptr<fftjet::ClusteringTreeSparsifier<fftjet::Peak,long> >
00431 fftjet_ClusteringTreeSparsifier_parser(const edm::ParameterSet& ps)
00432 {
00433     typedef std::auto_ptr<fftjet::ClusteringTreeSparsifier<fftjet::Peak,long> > return_type;
00434 
00435     const int maxLevelNumber = ps.getParameter<int>("maxLevelNumber");
00436     const unsigned filterMask = ps.getParameter<unsigned>("filterMask");
00437     const std::vector<double> userScalesV = 
00438         ps.getParameter<std::vector<double> >("userScales");
00439     const unsigned nUserScales = userScalesV.size();
00440     const double* userScales = nUserScales ? NULL : &userScalesV[0];
00441 
00442     return return_type(
00443         new fftjet::ClusteringTreeSparsifier<fftjet::Peak,long>(
00444             maxLevelNumber,
00445             filterMask,
00446             userScales,
00447             nUserScales
00448             )
00449         );
00450 }
00451 
00452 
00453 std::auto_ptr<fftjet::AbsDistanceCalculator<fftjet::Peak> >
00454 fftjet_DistanceCalculator_parser(const edm::ParameterSet& ps)
00455 {
00456     typedef std::auto_ptr<fftjet::AbsDistanceCalculator<fftjet::Peak> > return_type;
00457 
00458     const std::string calc_type = ps.getParameter<std::string>("Class");
00459 
00460     if (!calc_type.compare("PeakEtaPhiDistance"))
00461     {
00462         const double etaToPhiBandwidthRatio = ps.getParameter<double>(
00463             "etaToPhiBandwidthRatio");
00464         return return_type(new fftjet::PeakEtaPhiDistance(etaToPhiBandwidthRatio));
00465     }
00466 
00467     if (!calc_type.compare("PeakEtaDependentDistance"))
00468     {
00469         std::auto_ptr<fftjet::LinearInterpolator1d> interp = 
00470             fftjet_LinearInterpolator1d_parser(
00471                 ps.getParameter<edm::ParameterSet>("Interpolator"));
00472         const fftjet::LinearInterpolator1d* ip = interp.get();
00473         if (ip == NULL)
00474             return return_type(NULL);
00475 
00476         // Check that the interpolator is always positive
00477         const unsigned n = ip->nx();
00478         const double* data = ip->getData();
00479         for (unsigned i=0; i<n; ++i)
00480             if (data[i] <= 0.0)
00481                 return return_type(NULL);
00482         if (ip->fLow() <= 0.0 || ip->fHigh() <= 0.0)
00483             return return_type(NULL);
00484 
00485         return return_type(new fftjet::PeakEtaDependentDistance(*ip));
00486     }
00487 
00488     return return_type(NULL);
00489 }
00490 
00491 
00492 std::auto_ptr<fftjet::LinearInterpolator1d>
00493 fftjet_LinearInterpolator1d_parser(const edm::ParameterSet& ps)
00494 {
00495     const double xmin = ps.getParameter<double>("xmin");
00496     const double xmax = ps.getParameter<double>("xmax");
00497     const double flow = ps.getParameter<double>("flow");
00498     const double fhigh = ps.getParameter<double>("fhigh");
00499     const std::vector<double> data(
00500         ps.getParameter<std::vector<double> >("data"));
00501     if (data.empty())
00502         return std::auto_ptr<fftjet::LinearInterpolator1d>(NULL);
00503     else
00504         return std::auto_ptr<fftjet::LinearInterpolator1d>(
00505             new fftjet::LinearInterpolator1d(
00506                 &data[0], data.size(), xmin, xmax, flow, fhigh));
00507 }
00508     
00509 
00510 std::auto_ptr<fftjet::Functor1<double,fftjet::Peak> >
00511 fftjet_PeakFunctor_parser(const edm::ParameterSet& ps)
00512 {
00513     typedef fftjet::Functor1<double,fftjet::Peak> ptr_type;
00514     typedef std::auto_ptr<ptr_type> return_type;
00515 
00516     const std::string property_type = ps.getParameter<std::string>("Class");
00517 
00518     if (!property_type.compare("Log"))
00519     {
00520         return_type wrapped = fftjet_PeakFunctor_parser(
00521             ps.getParameter<edm::ParameterSet>("function"));
00522         ptr_type* wr = wrapped.get();
00523         if (wr)
00524         {
00525             return_type result = return_type(
00526                 new fftjet::LogProperty<fftjet::Peak>(wr, true));
00527             wrapped.release();
00528             return result;
00529         }
00530     }
00531 
00532     if (!property_type.compare("PeakProperty"))
00533     {
00534         const std::string member = ps.getParameter<std::string>("member");
00535         fftjet::JetProperty<fftjet::Peak>::JetMemberFunction fcn;
00536         if (parse_peak_member_function(member.c_str(), &fcn))
00537             return return_type(
00538                 new fftjet::JetProperty<fftjet::Peak>(fcn));
00539         else
00540             return return_type(NULL);
00541     }
00542 
00543     if (!property_type.compare("MinusScaledLaplacian"))
00544     {
00545         const double sx = ps.getParameter<double>("sx");
00546         const double sy = ps.getParameter<double>("sx");
00547         return return_type(
00548             new fftjet::MinusScaledLaplacian<fftjet::Peak>(sx, sy));
00549     }
00550 
00551     if (!property_type.compare("ScaledHessianDet"))
00552     {
00553         return return_type(
00554             new fftjet::ScaledHessianDet<fftjet::Peak>());
00555     }
00556 
00557     if (!property_type.compare("ScaledMagnitude"))
00558     {
00559         return return_type(
00560             new fftjet::ScaledMagnitude<fftjet::Peak>());
00561     }
00562 
00563     if (!property_type.compare("ScaledMagnitude2"))
00564     {
00565         return return_type(
00566             new fftjet::ScaledMagnitude2<fftjet::Peak>());
00567     }
00568 
00569     if (!property_type.compare("ConstDouble"))
00570     {
00571         const double value = ps.getParameter<double>("value");
00572         return return_type(new ConstDouble<fftjet::Peak>(value));
00573     }
00574 
00575     if (!property_type.compare("ProportionalToScale"))
00576     {
00577         const double value = ps.getParameter<double>("value");
00578         return return_type(
00579             new ProportionalToScale<fftjet::Peak>(value));
00580     }
00581 
00582     if (!property_type.compare("MultiplyByConst"))
00583     {
00584         const double factor = ps.getParameter<double>("factor");
00585         return_type function = fftjet_PeakFunctor_parser(
00586             ps.getParameter<edm::ParameterSet>("function"));
00587         ptr_type* ptr = function.get();
00588         if (ptr)
00589         {
00590             return_type result = return_type(
00591                 new MultiplyByConst<fftjet::Peak>(factor, ptr, true));
00592             function.release();
00593             return result;
00594         }
00595     }
00596 
00597     if (!property_type.compare("CompositeFunctor"))
00598     {
00599         std::auto_ptr<fftjet::Functor1<double,double> > fcn1 = 
00600             fftjet_Function_parser(
00601                 ps.getParameter<edm::ParameterSet>("function1"));
00602         return_type fcn2 = fftjet_PeakFunctor_parser(
00603             ps.getParameter<edm::ParameterSet>("function2"));
00604         fftjet::Functor1<double,double>* f1 = fcn1.get();
00605         ptr_type* f2 = fcn2.get();
00606         if (f1 && f2)
00607         {
00608             return_type result = return_type(
00609                 new CompositeFunctor<fftjet::Peak>(f1, f2, true));
00610             fcn1.release();
00611             fcn2.release();
00612             return result;
00613         }
00614     }
00615 
00616     if (!property_type.compare("ProductFunctor"))
00617     {
00618         return_type fcn1 = fftjet_PeakFunctor_parser(
00619             ps.getParameter<edm::ParameterSet>("function1"));
00620         return_type fcn2 = fftjet_PeakFunctor_parser(
00621             ps.getParameter<edm::ParameterSet>("function2"));
00622         ptr_type* f1 = fcn1.get();
00623         ptr_type* f2 = fcn2.get();
00624         if (f1 && f2)
00625         {
00626             return_type result = return_type(
00627                 new ProductFunctor<fftjet::Peak>(f1, f2, true));
00628             fcn1.release();
00629             fcn2.release();
00630             return result;
00631         }
00632     }
00633 
00634     if (!property_type.compare("MagnitudeDependent"))
00635     {
00636         std::auto_ptr<fftjet::Functor1<double,double> > fcn1 = 
00637             fftjet_Function_parser(
00638                 ps.getParameter<edm::ParameterSet>("function"));
00639         fftjet::Functor1<double,double>* f1 = fcn1.get();
00640         if (f1)
00641         {
00642             return_type result = return_type(
00643                 new MagnitudeDependent<fftjet::Peak>(f1, true));
00644             fcn1.release();
00645             return result;
00646         }
00647     }
00648 
00649     if (!property_type.compare("PeakEtaDependent"))
00650     {
00651         std::auto_ptr<fftjet::Functor1<double,double> > fcn1 = 
00652             fftjet_Function_parser(
00653                 ps.getParameter<edm::ParameterSet>("function"));
00654         fftjet::Functor1<double,double>* f1 = fcn1.get();
00655         if (f1)
00656         {
00657             return_type result = return_type(new PeakEtaDependent(f1, true));
00658             fcn1.release();
00659             return result;
00660         }
00661     }
00662 
00663     return return_type(NULL);
00664 }
00665 
00666 
00667 std::auto_ptr<fftjet::Functor1<double,fftjet::RecombinedJet<VectorLike> > >
00668 fftjet_JetFunctor_parser(const edm::ParameterSet& ps)
00669 {
00670     typedef fftjet::Functor1<double,RecoFFTJet> ptr_type;
00671     typedef std::auto_ptr<ptr_type> return_type;
00672 
00673     const std::string property_type = ps.getParameter<std::string>("Class");
00674 
00675     if (!property_type.compare("Log"))
00676     {
00677         return_type wrapped = fftjet_JetFunctor_parser(
00678             ps.getParameter<edm::ParameterSet>("function"));
00679         fftjet::Functor1<double,RecoFFTJet>* wr = wrapped.get();
00680         if (wr)
00681         {
00682             return_type result = return_type(
00683                 new fftjet::LogProperty<RecoFFTJet>(wr, true));
00684             wrapped.release();
00685             return result;
00686         }
00687     }
00688 
00689     if (!property_type.compare("JetEtaDependent"))
00690     {
00691         std::auto_ptr<fftjet::Functor1<double,double> > fcn1 = 
00692             fftjet_Function_parser(
00693                 ps.getParameter<edm::ParameterSet>("function"));
00694         fftjet::Functor1<double,double>* f1 = fcn1.get();
00695         if (f1)
00696         {
00697             return_type result = return_type(new JetEtaDependent(f1, true));
00698             fcn1.release();
00699             return result;
00700         }
00701     }
00702 
00703     if (!property_type.compare("JetProperty"))
00704     {
00705         const std::string member = ps.getParameter<std::string>("member");
00706         fftjet::JetProperty<RecoFFTJet>::JetMemberFunction fcn;
00707         if (parse_jet_member_function(member.c_str(), &fcn))
00708             return return_type(
00709                 new fftjet::JetProperty<RecoFFTJet>(fcn));
00710         else
00711             return return_type(NULL);
00712     }
00713 
00714     if (!property_type.compare("ConstDouble"))
00715     {
00716         const double value = ps.getParameter<double>("value");
00717         return return_type(new ConstDouble<RecoFFTJet>(value));
00718     }
00719 
00720     if (!property_type.compare("ProportionalToScale"))
00721     {
00722         const double value = ps.getParameter<double>("value");
00723         return return_type(
00724             new ProportionalToScale<RecoFFTJet>(value));
00725     }
00726 
00727     if (!property_type.compare("MultiplyByConst"))
00728     {
00729         const double factor = ps.getParameter<double>("factor");
00730         return_type function = fftjet_JetFunctor_parser(
00731             ps.getParameter<edm::ParameterSet>("function"));
00732         ptr_type* ptr = function.get();
00733         if (ptr)
00734         {
00735             return_type result = return_type(
00736                 new MultiplyByConst<RecoFFTJet>(factor, ptr, true));
00737             function.release();
00738             return result;
00739         }
00740     }
00741 
00742     if (!property_type.compare("CompositeFunctor"))
00743     {
00744         std::auto_ptr<fftjet::Functor1<double,double> > fcn1 = 
00745             fftjet_Function_parser(
00746                 ps.getParameter<edm::ParameterSet>("function1"));
00747         return_type fcn2 = fftjet_JetFunctor_parser(
00748             ps.getParameter<edm::ParameterSet>("function2"));
00749         fftjet::Functor1<double,double>* f1 = fcn1.get();
00750         ptr_type* f2 = fcn2.get();
00751         if (f1 && f2)
00752         {
00753             return_type result = return_type(
00754                 new CompositeFunctor<RecoFFTJet>(f1, f2, true));
00755             fcn1.release();
00756             fcn2.release();
00757             return result;
00758         }
00759     }
00760 
00761     if (!property_type.compare("ProductFunctor"))
00762     {
00763         return_type fcn1 = fftjet_JetFunctor_parser(
00764             ps.getParameter<edm::ParameterSet>("function1"));
00765         return_type fcn2 = fftjet_JetFunctor_parser(
00766             ps.getParameter<edm::ParameterSet>("function2"));
00767         ptr_type* f1 = fcn1.get();
00768         ptr_type* f2 = fcn2.get();
00769         if (f1 && f2)
00770         {
00771             return_type result = return_type(
00772                 new ProductFunctor<RecoFFTJet>(f1, f2, true));
00773             fcn1.release();
00774             fcn2.release();
00775             return result;
00776         }
00777     }
00778 
00779     if (!property_type.compare("MagnitudeDependent"))
00780     {
00781         std::auto_ptr<fftjet::Functor1<double,double> > fcn1 = 
00782             fftjet_Function_parser(
00783                 ps.getParameter<edm::ParameterSet>("function"));
00784         fftjet::Functor1<double,double>* f1 = fcn1.get();
00785         if (f1)
00786         {
00787             return_type result = return_type(
00788                 new MagnitudeDependent<RecoFFTJet>(f1, true));
00789             fcn1.release();
00790             return result;
00791         }
00792     }
00793 
00794     return return_type(NULL);
00795 }
00796 
00797 
00798 std::auto_ptr<fftjet::Functor2<double,
00799                                fftjet::RecombinedJet<VectorLike>,
00800                                fftjet::RecombinedJet<VectorLike> > >
00801 fftjet_JetDistance_parser(const edm::ParameterSet& ps)
00802 {
00803     typedef std::auto_ptr<fftjet::Functor2<
00804         double,
00805         fftjet::RecombinedJet<VectorLike>,
00806         fftjet::RecombinedJet<VectorLike> > > return_type;
00807 
00808     const std::string distance_type = ps.getParameter<std::string>(
00809         "Class");
00810 
00811     if (!distance_type.compare("JetConvergenceDistance"))
00812     {
00813         make_param(double, etaToPhiBandwidthRatio);
00814         make_param(double, relativePtBandwidth);
00815 
00816         if (etaToPhiBandwidthRatio > 0.0 && relativePtBandwidth > 0.0)
00817             return return_type(new JetConvergenceDistance(
00818                 etaToPhiBandwidthRatio, relativePtBandwidth));
00819     }
00820 
00821     return return_type(NULL);
00822 }
00823 
00824 
00825 std::auto_ptr<fftjet::Functor1<double,double> >
00826 fftjet_Function_parser(const edm::ParameterSet& ps)
00827 {
00828     typedef std::auto_ptr<fftjet::Functor1<double,double> > return_type;
00829 
00830     const std::string fcn_type = ps.getParameter<std::string>("Class");
00831 
00832     if (!fcn_type.compare("LinearInterpolator1d"))
00833     {
00834         std::auto_ptr<fftjet::LinearInterpolator1d> p = 
00835             fftjet_LinearInterpolator1d_parser(ps);
00836         fftjet::LinearInterpolator1d* ptr = p.get();
00837         if (ptr)
00838         {
00839             p.release();
00840             return return_type(ptr);
00841         }
00842     }
00843 
00844     if (!fcn_type.compare("Polynomial"))
00845     {
00846         std::vector<double> coeffs;
00847         for (unsigned i=0; ; ++i)
00848         {
00849             std::ostringstream s;
00850             s << 'c' << i;
00851             if (ps.exists(s.str()))
00852                 coeffs.push_back(ps.getParameter<double>(s.str()));
00853             else
00854                 break;
00855         }
00856         return return_type(new Polynomial(coeffs));
00857     }
00858 
00859     return return_type(NULL);
00860 }
00861 
00862 }