CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DetectorDescription/ExprAlgo/src/AlgoPos.cc

Go to the documentation of this file.
00001 
00002 #include "DetectorDescription/ExprAlgo/interface/AlgoPos.h"
00003 #include "DetectorDescription/ExprAlgo/interface/AlgoImpl.h"
00004 #include "DetectorDescription/ExprAlgo/interface/AlgoCheck.h"
00005 #include "DetectorDescription/Base/interface/DDException.h"
00006 
00007 using namespace std;
00008 
00009 AlgoPos::AlgoPos(AlgoCheck * check)
00010  : start_(0), end_(0), incr_(0), curr_(0), count_(0),
00011    terminate_(false), selAlgo_(0), checkAlgo_(check)
00012 { }
00013 
00014 
00015 AlgoPos::~AlgoPos()
00016 { 
00017   //FIXME: delete all registered AlgoImpls!!!
00018   std::vector<AlgoImpl*>::iterator it = regAlgos_.begin();
00019   for (; it != regAlgos_.end(); ++it) {
00020     delete *it;
00021   }  
00022   delete checkAlgo_; 
00023 }
00024 
00025 
00026 void AlgoPos::setParameters(int start, int end, int incr,
00027                             const parS_type & ps, const parE_type & pe)
00028 {
00029   // init the algorithm when parameters are set
00030   terminate_ = false;
00031   start_     = start;
00032   end_       = end;
00033   incr_      = incr;
00034   if (incr>0) curr_ = start;
00035   if (incr<0) curr_ = end;  
00036   count_ = 1;
00037 
00038   // now check mandatory parameters, then let the algorithm check all parametes itself.
00039   // collect all error messages in std::string err_
00040   
00041   bool check = true;
00042   if (incr) {
00043     if (start>=end) {
00044       check = false;
00045     }  
00046   }
00047   if (!check) err_ = "\twrong range specification: (start<end && incr!=0)==false, [start,end,incr]=["
00048                    + AlgoImpl::d2s(start) + "," 
00049                    + AlgoImpl::d2s(end) + "," 
00050                    + AlgoImpl::d2s(incr) + "]\n" ;
00051 
00052   if (incr==0) {
00053     if ( (start!=0) || (end!=0) ) {
00054       err_ += "\tincr==0 requires start==0 and end==0 in the range. range: [start,end,incr]=["
00055                    + AlgoImpl::d2s(start) + "," 
00056                    + AlgoImpl::d2s(end) + "," 
00057                    + AlgoImpl::d2s(incr) + "]\n" ;
00058       check = false;               
00059 
00060     }
00061   }     
00062                            
00063   // select one of the registered algorithm implementations
00064   ParS_ = ps;
00065   ParE_ = pe;
00066   if (!select()) check = false;
00067   
00068   if (!check) 
00069     throw DDException(err_);
00070 }
00071 
00072 
00073 void AlgoPos::registerAlgo(AlgoImpl*a)
00074 {
00075   regAlgos_.push_back(a);
00076 }
00077 
00078 size_t AlgoPos::numRegistered()
00079 {
00080   return regAlgos_.size();
00081 }
00082 
00083 int AlgoPos::copyno() const
00084 {
00085   return selAlgo_->copyno();
00086 }
00087 
00088 
00097 void AlgoPos::next()
00098 {
00099   // increase the invocation count of the algorithm
00100   ++count_;
00101   
00102   
00103   // iterate to the next position in the range [start_,end_,incr_]
00104   // only if incr_ != 0
00105   
00106   if (incr_>0) {
00107     curr_ += incr_;
00108     if (curr_>end_) {
00109       terminate();
00110     }  
00111   }
00112   
00113   if (incr_<0) {
00114     curr_ += incr_;
00115     if (curr_<start_) {
00116       terminate();
00117     }  
00118   }
00119   
00120   // incr_==0: the algorithm has to self-check whether to terminate
00121   if (incr_==0) {
00122     checkTermination();
00123   }
00124 }
00125 
00126 
00127 
00128 void AlgoPos::checkTermination()
00129 { 
00130   selAlgo_->checkTermination();
00131 }
00132 
00133 
00134 void AlgoPos::terminate()
00135 { 
00136   terminate_=true; 
00137 }
00138 
00139 
00140 bool AlgoPos::go() const 
00141 { 
00142   return !terminate_; 
00143 }
00144 
00145 
00146 DD3Vector AlgoPos::translation()
00147 {
00148   return selAlgo_->translation();
00149 }
00150 
00151 
00152 DDRotationMatrix AlgoPos::rotation()
00153 {
00154   return selAlgo_->rotation();
00155 }
00156 
00157 
00158 bool AlgoPos::select()
00159 {
00160   bool result = false;
00161   
00162   // if constraints checking is enabled (object checkAlgo_ is there) ,
00163   // check the contraints of the parameters as specified in the schema.
00164   if (checkAlgo_) {
00165     result = (checkAlgo_->check(ParS_,ParE_,err_));
00166   }
00167   else {
00168     result = true;
00169   }  
00170   
00171   
00172   if (result) { // select an algorithm-implementation only if the parameters are ok
00173     std::vector<AlgoImpl*>::iterator it = regAlgos_.begin();
00174     for (; it != regAlgos_.end(); ++it) {
00175       std::string::size_type s = err_.size();
00176       result = (*it)->checkParameters();
00177       if (s!=err_.size()) { // uups, error-std::string was modified! tell it, where:
00178         err_ += std::string("\tin algo.implementation labeled \"") + (*it)->label_ + std::string("\"\n");
00179       }
00180       if (result) { // select the algorithm
00181         selAlgo_ = *it;
00182         break;
00183       }  
00184     }
00185   }  
00186   // parameters are not ok, put something into the error message
00187   /*
00188   if (!result) { 
00189    err_ += "\tin algorithm named " + std::string("[") 
00190         +  ns() + std::string(":") + name() + std::string("]\n");
00191   }     
00192   */   
00193   
00194   return result;
00195 }
00196 
00197 // stream information about the alog-parameters
00198 void AlgoPos::stream(ostream & os) const
00199 {
00200   os <<  "start=" << start_ << " end=" << end_ << " incr=" << incr_ << std::endl;
00201   parE_type::const_iterator eit = ParE_.begin();
00202   for (; eit != ParE_.end() ; ++eit) {
00203     std::vector<double>::const_iterator sit = eit->second.begin();
00204     os << "parE name=" << eit->first;
00205     for (; sit != eit->second.end(); ++sit) {
00206        os << " val=" << *sit << std::endl;
00207     }
00208   }
00209   parS_type::const_iterator stit = ParS_.begin();
00210   for (; stit != ParS_.end() ; ++stit) {
00211     std::vector<std::string>::const_iterator sit = stit->second.begin();
00212     os << "parS name=" << stit->first;
00213     for (; sit != stit->second.end(); ++sit) {
00214        os << " val=" << *sit << std::endl;
00215     }
00216   }
00217 }