00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OPENMS_TRANSFORMATIONS_FEATUREFINDER_PRODUCTMODEL_H
00029 #define OPENMS_TRANSFORMATIONS_FEATUREFINDER_PRODUCTMODEL_H
00030
00031 #include <OpenMS/TRANSFORMATIONS/FEATUREFINDER/BaseModel.h>
00032 #include <OpenMS/TRANSFORMATIONS/FEATUREFINDER/ModelDescription.h>
00033 #include <OpenMS/KERNEL/RawDataPoint2D.h>
00034
00035 namespace OpenMS
00036 {
00046 template <UInt D>
00047 class ProductModel
00048 : public BaseModel<D>
00049 {
00050
00051 public:
00052 typedef typename DPeak<D>::IntensityType IntensityType;
00053 typedef DPosition<D> PositionType;
00054 typedef DPeakArray<DPeak<D> > SamplesType;
00055
00057 ProductModel()
00058 : BaseModel<D>(),
00059 distributions_(D,0)
00060 {
00061 this->setName(this->getProductName());
00062
00063
00064 for (UInt dim=0; dim<D; ++dim)
00065 {
00066 String name = RawDataPoint2D::shortDimensionName(dim);
00067 this->subsections_.push_back(name);
00068 this->defaults_.setValue(name,"GaussModel","Name of the model used for this dimension");
00069 }
00070
00071
00072 this->defaults_.setValue("intensity_scaling",1.0,"Scaling factor used to adjust the model distribution to the intensities of the data");
00073 this->defaultsToParam_();
00074 }
00075
00077 ProductModel(const ProductModel& source)
00078 : BaseModel<D>(source),
00079 distributions_(D,0),
00080 scale_(source.scale_)
00081 {
00082 for (UInt dim=0; dim<D; ++dim)
00083 {
00084
00085 if (source.distributions_[dim])
00086 {
00087 ModelDescription<1> desc(source.distributions_[dim]);
00088 setModel(dim,desc.createModel());
00089 }
00090 }
00091 updateMembers_();
00092 }
00093
00095 virtual ~ProductModel()
00096 {
00097 for (UInt dim=0; dim<D; ++dim)
00098 {
00099 delete distributions_[dim];
00100 }
00101 }
00102
00104 virtual ProductModel& operator = (const ProductModel& source)
00105 {
00106 if (&source == this) return *this;
00107
00108 BaseModel<D>::operator = (source);
00109 scale_ = source.scale_;
00110
00111 for (UInt dim=0; dim<D; ++dim)
00112 {
00113 if (source.distributions_[dim])
00114 {
00115
00116 ModelDescription<1> desc(source.distributions_[dim]);
00117 setModel(dim,desc.createModel());
00118 }
00119 else
00120 {
00121 distributions_[dim] = 0;
00122 }
00123 }
00124 updateMembers_();
00125
00126 return *this;
00127 }
00128
00130 IntensityType getIntensity(const PositionType& pos) const
00131 {
00132 IntensityType intens(scale_);
00133 for (UInt dim=0; dim<D; ++dim)
00134 {
00135 if (distributions_[dim]==0)
00136 {
00137 throw Exception::Base(__FILE__, __LINE__, __PRETTY_FUNCTION__, String("ProductModel: model for dimension ") + dim + " not set.","");
00138 }
00139 intens *= distributions_[dim]->getIntensity(pos[dim]);
00140 }
00141 return intens;
00142 }
00143
00145 static BaseModel<D>* create()
00146 {
00147 return new ProductModel<D>();
00148 }
00149
00151 static const String getProductName()
00152 {
00153 return String("ProductModel") + D + "D";
00154 }
00155
00163 ProductModel& setModel(UInt dim, BaseModel<1>* dist)
00164 {
00165 OPENMS_PRECONDITION(dim<D, "ProductModel<D>:getModel(Position): index overflow!");
00166 if (dist==0 || dist==distributions_[dim])
00167 {
00168 return *this;
00169 }
00170
00171 delete distributions_[dim];
00172 distributions_[dim] = dist;
00173
00174
00175 String name = RawDataPoint2D::shortDimensionName(dim);
00176 this->param_.remove(name + ':');
00177 this->param_.insert(name + ':',distributions_[dim]->getParameters());
00178 this->param_.setValue(name, distributions_[dim]->getName());
00179
00180 return *this;
00181 }
00182
00183 BaseModel<1>* getModel(UInt dim) const
00184 {
00185 OPENMS_PRECONDITION(dim<D, "ProductModel<D>:getModel(Position): index overflow!");
00186 return distributions_[dim];
00187 }
00188
00190 IntensityType getScale() const
00191 {
00192 return scale_;
00193 }
00194
00196 void setScale(IntensityType scale)
00197 {
00198 this->setCutOff( this->getCutOff()/scale_ );
00199 scale_ = scale;
00200 this->param_.setValue("intensity_scaling",scale);
00201 this->setCutOff( this->getCutOff()*scale_ );
00202 }
00203
00205 void getSamples(SamplesType& cont) const
00206 {
00207 cont = SamplesType();
00208 typedef typename BaseModel<1>::SamplesType Samples1D;
00209 std::vector<Samples1D> samples(D);
00210
00211 for (UInt dim=0; dim<D; ++dim)
00212 {
00213 distributions_[dim]->getSamples(samples[dim]);
00214 }
00215
00216 typename BaseModel<D>::PeakType peak;
00217 std::vector<UInt> i(D,0);
00218
00219 while(i[D-1]<samples[D-1].size())
00220 {
00221 for (UInt dim=0; dim<D; ++dim)
00222 {
00223 peak.getPosition()[dim] = samples[dim][ i[dim] ].getPosition()[0];
00224 }
00225 fillIntensity(peak);
00226 cont.push_back(peak);
00227
00228 ++i[0];
00229 for (UInt dim=0; dim<D-1; ++dim)
00230 {
00231 if (i[dim]>=samples[dim].size())
00232 {
00233 i[dim]=0;
00234 ++i[dim+1];
00235 }
00236 }
00237 }
00238 }
00239
00240 protected:
00241 void updateMembers_()
00242 {
00243 BaseModel<D>::updateMembers_();
00244 scale_ = (double)(this->param_.getValue("intensity_scaling"));
00245 for (UInt dim=0; dim<D; ++dim)
00246 {
00247 String name = RawDataPoint2D::shortDimensionName(dim);
00248 if (this->param_.exists(name))
00249 {
00250 delete distributions_[dim];
00251 distributions_[dim] = Factory< BaseModel<1> >::create(this->param_.getValue(name));
00252 Param copy = this->param_.copy(name+":",true);
00253 distributions_[dim]->setParameters(copy);
00254 }
00255 }
00256 }
00257
00258 std::vector< BaseModel<1>* > distributions_;
00259 IntensityType scale_;
00260 };
00261 }
00262
00263 #endif // OPENMS_TRANSFORMATIONS_FEATUREFINDER_PRODUCTMODEL_H