CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/FWCore/Framework/src/ProductHolder.cc

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------
00002 ----------------------------------------------------------------------*/
00003 #include "FWCore/Framework/interface/ProductHolder.h"
00004 #include "FWCore/Framework/interface/Principal.h"
00005 #include "FWCore/Framework/interface/ProductDeletedException.h"
00006 
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "FWCore/Utilities/interface/TypeID.h"
00009 
00010 #include <cassert>
00011 
00012 namespace edm {
00013 
00014   void ProductHolderBase::throwProductDeletedException() const {
00015     ProductDeletedException exception;
00016     exception << "ProductHolderBase::resolveProduct_: The product matching all criteria was already deleted\n"
00017       << "Looking for type: " << branchDescription().unwrappedTypeID() << "\n"
00018       << "Looking for module label: " << moduleLabel() << "\n"
00019       << "Looking for productInstanceName: " << productInstanceName() << "\n"
00020       << (processName().empty() ? "" : "Looking for process: ") << processName() << "\n"
00021       << "This means there is a configuration error.\n"
00022       << "The module which is asking for this data must be configured to state that it will read this data.";
00023     throw exception;
00024     
00025   }
00026   
00027   ProductHolderBase::ProductHolderBase() {}
00028 
00029   ProductHolderBase::~ProductHolderBase() {}
00030   InputProductHolder::~InputProductHolder() {}
00031   ProducedProductHolder::~ProducedProductHolder() {}
00032   ScheduledProductHolder::~ScheduledProductHolder() {}
00033   UnscheduledProductHolder::~UnscheduledProductHolder() {}
00034   SourceProductHolder::~SourceProductHolder() {}
00035   AliasProductHolder::~AliasProductHolder() {}
00036   NoProcessProductHolder::~NoProcessProductHolder() {}
00037 
00038   ProductData const*
00039   InputProductHolder::resolveProduct_(ResolveStatus& resolveStatus, bool) const {
00040     if(productWasDeleted()) {
00041       throwProductDeletedException();
00042     }
00043     if(!productUnavailable()) {
00044       principal_->resolveProduct(*this, false);
00045       // If the product is a dummy filler, product holder will now be marked unavailable.
00046       if(product() && !productUnavailable()) {
00047         // Found the match
00048         resolveStatus = ProductFound;
00049         return &productData_;
00050       }
00051     }
00052     resolveStatus = ProductNotFound;
00053     return nullptr;
00054   }
00055 
00056   ProductData const*
00057   ScheduledProductHolder::resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const {
00058     if (!skipCurrentProcess) {
00059       if(productWasDeleted()) {
00060         throwProductDeletedException();
00061       }
00062       if(product() && wrapper().isPresent()) {
00063         resolveStatus = ProductFound;
00064         return &productData_;
00065       }
00066     }
00067     resolveStatus = ProductNotFound;
00068     return nullptr;
00069   }
00070 
00071   ProductData const*
00072   SourceProductHolder::resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const {
00073     if (!skipCurrentProcess) {
00074       if(productWasDeleted()) {
00075         throwProductDeletedException();
00076       }
00077       if(product() && wrapper().isPresent()) {
00078         resolveStatus = ProductFound;
00079         return &productData_;
00080       }
00081     }
00082     resolveStatus = ProductNotFound;
00083     return nullptr;
00084   }
00085 
00086   ProductData const*
00087   UnscheduledProductHolder::resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const {
00088     if (!skipCurrentProcess) {
00089       if(productWasDeleted()) {
00090         throwProductDeletedException();
00091       }
00092       if(product() && wrapper().isPresent()) {
00093         resolveStatus = ProductFound;
00094         return &productData_;
00095       }
00096       principal_->unscheduledFill(moduleLabel());
00097       if(product() && wrapper().isPresent()) {
00098         resolveStatus = ProductFound;
00099         return &productData_;
00100       }
00101     }
00102     resolveStatus = ProductNotFound;
00103     return nullptr;
00104   }
00105 
00106   void
00107   ProducedProductHolder::putProduct_(
00108         WrapperOwningHolder const& edp,
00109         ProductProvenance const& productProvenance) {
00110     if(product()) {
00111       throw Exception(errors::InsertFailure)
00112           << "Attempt to insert more than one product on branch " << branchDescription().branchName() << "\n";
00113     }
00114     assert(branchDescription().produced());
00115     assert(edp.isValid());
00116     assert(!provenance()->productProvenanceValid());
00117     assert(status() != Present);
00118     assert(status() != Uninitialized);
00119     setProductProvenance(productProvenance);
00120     assert(provenance()->productProvenanceValid());
00121     if(productData().getInterface() != 0) {
00122       assert(productData().getInterface()->sameType(*edp.interface()));
00123     }
00124     productData().wrapper_ = edp.product();
00125     status_() = Present;
00126   }
00127 
00128   void
00129   ProducedProductHolder::mergeProduct_(
00130         WrapperOwningHolder const& edp,
00131         ProductProvenance& productProvenance) {
00132     assert(provenance()->productProvenanceValid());
00133     assert(status() == Present);
00134     setProductProvenance(productProvenance);
00135     mergeTheProduct(edp);
00136   }
00137 
00138   bool
00139   ProducedProductHolder::putOrMergeProduct_() const {
00140     return productUnavailable();
00141   }
00142 
00143   void
00144   ProducedProductHolder::mergeProduct_(WrapperOwningHolder const& edp) const {
00145     assert(status() == Present);
00146     mergeTheProduct(edp);
00147   }
00148 
00149   void
00150   ProducedProductHolder::putProduct_(WrapperOwningHolder const& edp) const {
00151     if(product()) {
00152       throw Exception(errors::InsertFailure)
00153           << "Attempt to insert more than one product on branch " << branchDescription().branchName() << "\n";
00154     }
00155     assert(branchDescription().produced());
00156     assert(edp.isValid());
00157     assert(status() != Present);
00158     assert(status() != Uninitialized);
00159     if(productData().getInterface() != 0) {
00160       assert(productData().getInterface()->sameType(*edp.interface()));
00161     }
00162     productData().wrapper_ = edp.product();
00163     status_() = Present;
00164   }
00165 
00166   void
00167   InputProductHolder::putProduct_(
00168         WrapperOwningHolder const& edp,
00169         ProductProvenance const& productProvenance) {
00170     assert(!product());
00171     assert(!provenance()->productProvenanceValid());
00172     setProductProvenance(productProvenance);
00173     assert(provenance()->productProvenanceValid());
00174     setProduct(edp);
00175   }
00176 
00177   void
00178   InputProductHolder::mergeProduct_(
00179         WrapperOwningHolder const&,
00180         ProductProvenance&) {
00181     assert(nullptr);
00182   }
00183 
00184   void
00185   InputProductHolder::mergeProduct_(WrapperOwningHolder const& edp) const {
00186     mergeTheProduct(edp);
00187   }
00188 
00189   bool
00190   InputProductHolder::putOrMergeProduct_() const {
00191     return(!product());
00192   }
00193 
00194   void
00195   InputProductHolder::putProduct_(WrapperOwningHolder const& edp) const {
00196     assert(!product());
00197     setProduct(edp);
00198   }
00199 
00200   void
00201   ProductHolderBase::mergeTheProduct(WrapperOwningHolder const& edp) const {
00202     if(wrapper().isMergeable()) {
00203       wrapper().mergeProduct(edp.wrapper());
00204     } else if(wrapper().hasIsProductEqual()) {
00205       if(!wrapper().isProductEqual(edp.wrapper())) {
00206         LogError("RunLumiMerging")
00207               << "ProductHolderBase::mergeTheProduct\n"
00208               << "Two run/lumi products for the same run/lumi which should be equal are not\n"
00209               << "Using the first, ignoring the second\n"
00210               << "className = " << branchDescription().className() << "\n"
00211               << "moduleLabel = " << moduleLabel() << "\n"
00212               << "instance = " << productInstanceName() << "\n"
00213               << "process = " << processName() << "\n";
00214       }
00215     } else {
00216       LogWarning("RunLumiMerging")
00217           << "ProductHolderBase::mergeTheProduct\n"
00218           << "Run/lumi product has neither a mergeProduct nor isProductEqual function\n"
00219           << "Using the first, ignoring the second in merge\n"
00220           << "className = " << branchDescription().className() << "\n"
00221           << "moduleLabel = " << moduleLabel() << "\n"
00222           << "instance = " << productInstanceName() << "\n"
00223           << "process = " << processName() << "\n";
00224     }
00225   }
00226 
00227   void
00228   InputProductHolder::setProduct(WrapperOwningHolder const& prod) const {
00229     assert (!product());
00230     if(!prod.isValid() || !prod.isPresent()) {
00231       setProductUnavailable();
00232     }
00233     assert(!prod.isValid() || productData().getInterface()->sameType(*prod.interface()));
00234     productData().wrapper_ = prod.product();
00235   }
00236 
00237   void InputProductHolder::setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid) {
00238     productData().prov_.setProductID(pid);
00239     productData().prov_.setStore(mapper);
00240     productData().prov_.setProcessHistoryID(phid);
00241   }
00242 
00243   void InputProductHolder::setProcessHistoryID_(ProcessHistoryID const& phid) {
00244     productData().prov_.setProcessHistoryID(phid);
00245   }
00246 
00247   ProductProvenance* InputProductHolder::productProvenancePtr_() const {
00248     return provenance()->productProvenance();
00249   }
00250 
00251   void InputProductHolder::resetProductData_() {
00252     productData().resetProductData();
00253     resetStatus();
00254   }
00255 
00256   bool InputProductHolder::singleProduct_() const {
00257     return true;
00258   }
00259 
00260   void InputProductHolder::setPrincipal_(Principal* principal) {
00261     principal_ = principal;
00262   }
00263 
00264   void
00265   ProductHolderBase::setProductProvenance(ProductProvenance const& prov) const {
00266     productData().prov_.setProductProvenance(prov);
00267   }
00268 
00269   // This routine returns true if it is known that currently there is no real product.
00270   // If there is a real product, it returns false.
00271   // If it is not known if there is a real product, it returns false.
00272   bool
00273   InputProductHolder::productUnavailable_() const {
00274     if(productIsUnavailable()) {
00275       return true;
00276     }
00277     // If there is a product, we know if it is real or a dummy.
00278     if(product()) {
00279       bool unavailable = !(wrapper().isPresent());
00280       if(unavailable) {
00281         setProductUnavailable();
00282       }
00283       return unavailable;
00284     }
00285     return false;
00286   }
00287 
00288   // This routine returns true if it is known that currently there is no real product.
00289   // If there is a real product, it returns false.
00290   // If it is not known if there is a real product, it returns false.
00291   bool
00292   ProducedProductHolder::productUnavailable_() const {
00293     // If unscheduled production, the product is potentially available.
00294     if(onDemand()) return false;
00295     // The product is available if and only if a product has been put.
00296     bool unavailable = !(product() && wrapper().isPresent());
00297     return unavailable;
00298   }
00299 
00300   // This routine returns true if the product was deleted early in order to save memory
00301   bool
00302   ProducedProductHolder::productWasDeleted_() const {
00303     return status() == ProductDeleted;
00304   }
00305 
00306   void 
00307   ProducedProductHolder::setProductDeleted_() {
00308     status() = ProductDeleted;
00309   }
00310 
00311   void ProducedProductHolder::setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid) {
00312     productData().prov_.setProductID(pid);
00313     productData().prov_.setStore(mapper);
00314     productData().prov_.setProcessHistoryID(phid);
00315   }
00316 
00317   void ProducedProductHolder::setProcessHistoryID_(ProcessHistoryID const& phid) {
00318     productData().prov_.setProcessHistoryID(phid);
00319   }
00320   
00321   ProductProvenance* ProducedProductHolder::productProvenancePtr_() const {
00322     return provenance()->productProvenance();
00323   }
00324 
00325   void ProducedProductHolder::resetProductData_() {
00326     productData().resetProductData();
00327     resetStatus();
00328   }
00329 
00330   bool ProducedProductHolder::singleProduct_() const {
00331     return true;
00332   }
00333 
00334   void ProducedProductHolder::setPrincipal_(Principal* principal) {
00335     throw Exception(errors::LogicError)
00336       << "ProducedProductHolder::setPrincipal__() not implemented and should never be called.\n"
00337       << "Contact a Framework developer\n";
00338   }
00339 
00340   bool
00341   ProductHolderBase::provenanceAvailable() const {
00342     // If this product is from a the current process,
00343     // the provenance is available if and only if a product has been put.
00344     if(branchDescription().produced()) {
00345       return product() && wrapper().isPresent();
00346     }
00347     // If this product is from a prior process, the provenance is available,
00348     // although the per event part may have been dropped.
00349     return true;
00350   }
00351 
00352   TypeID
00353   ProductHolderBase::productType() const {
00354     return TypeID(wrapper().interface()->wrappedTypeInfo());
00355   }
00356 
00357   void
00358   ProductHolderBase::reallyCheckType(WrapperOwningHolder const& prod) const {
00359     // Check if the types match.
00360     TypeID typeID(prod.dynamicTypeInfo());
00361     if(typeID != branchDescription().unwrappedTypeID()) {
00362       // Types do not match.
00363       throw Exception(errors::EventCorruption)
00364           << "Product on branch " << branchDescription().branchName() << " is of wrong type.\n"
00365           << "It is supposed to be of type " << branchDescription().className() << ".\n"
00366           << "It is actually of type " << typeID.className() << ".\n";
00367     }
00368   }
00369 
00370   Provenance*
00371   ProductHolderBase::provenance() const {
00372     return &(productData().prov_);
00373   }
00374 
00375   void
00376   ProductHolderBase::write(std::ostream& os) const {
00377     // This is grossly inadequate. It is also not critical for the
00378     // first pass.
00379     os << std::string("ProductHolder for product with ID: ")
00380        << productID();
00381   }
00382 
00383   NoProcessProductHolder::
00384   NoProcessProductHolder(std::vector<ProductHolderIndex> const&  matchingHolders,
00385                          std::vector<bool> const& ambiguous,
00386                          Principal* principal) : 
00387     matchingHolders_(matchingHolders),
00388     ambiguous_(ambiguous),
00389     principal_(principal) {
00390     assert(ambiguous_.size() == matchingHolders_.size());
00391   }
00392 
00393   ProductData const& NoProcessProductHolder::getProductData() const {
00394     throw Exception(errors::LogicError)
00395       << "NoProcessProductHolder::getProductData() not implemented and should never be called.\n"
00396       << "Contact a Framework developer\n";
00397   }
00398 
00399   ProductData& NoProcessProductHolder::getProductData() {
00400     throw Exception(errors::LogicError)
00401       << "NoProcessProductHolder::getProductData() not implemented and should never be called.\n"
00402       << "Contact a Framework developer\n";
00403   }
00404 
00405   ProductData const* NoProcessProductHolder::resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const {
00406     std::vector<unsigned int> const& lookupProcessOrder = principal_->lookupProcessOrder();
00407     for(unsigned int k : lookupProcessOrder) {
00408       assert(k < ambiguous_.size());
00409       if(k == 0) break; // Done
00410       if(ambiguous_[k]) {
00411         resolveStatus = Ambiguous;
00412         return nullptr;
00413       }
00414       if (matchingHolders_[k] != ProductHolderIndexInvalid) {
00415         ProductHolderBase const* productHolder = principal_->getProductByIndex(matchingHolders_[k], false, false);
00416         ProductData const* pd =  productHolder->resolveProduct(resolveStatus, skipCurrentProcess);
00417         if(pd != nullptr) return pd;
00418       }
00419     }
00420     resolveStatus = ProductNotFound;
00421     return nullptr;
00422   }
00423 
00424   void AliasProductHolder::setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid) {
00425     productData().prov_.setProductID(pid);
00426     productData().prov_.setStore(mapper);
00427     productData().prov_.setProcessHistoryID(phid);
00428   }
00429 
00430   void AliasProductHolder::setProcessHistoryID_(ProcessHistoryID const& phid) {
00431     productData().prov_.setProcessHistoryID(phid);
00432   }
00433 
00434   ProductProvenance* AliasProductHolder::productProvenancePtr_() const {
00435     return provenance()->productProvenance();
00436   }
00437 
00438   void AliasProductHolder::resetProductData_() {
00439     productData().resetProductData();
00440     resetStatus();
00441   }
00442 
00443   bool AliasProductHolder::singleProduct_() const {
00444     return true;
00445   }
00446 
00447   void AliasProductHolder::setPrincipal_(Principal* principal) {
00448   }
00449 
00450   void NoProcessProductHolder::swap_(ProductHolderBase& rhs) {
00451     NoProcessProductHolder& other = dynamic_cast<NoProcessProductHolder&>(rhs);
00452     ambiguous_.swap(other.ambiguous_);
00453     matchingHolders_.swap(other.matchingHolders_);
00454     std::swap(principal_, other.principal_);
00455   }
00456 
00457   void NoProcessProductHolder::resetStatus_() {
00458   }
00459 
00460   void NoProcessProductHolder::setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid) {
00461   }
00462 
00463   void NoProcessProductHolder::setProcessHistoryID_(ProcessHistoryID const& phid) {
00464   }
00465 
00466   ProductProvenance* NoProcessProductHolder::productProvenancePtr_() const {
00467     return nullptr;
00468   }
00469 
00470   void NoProcessProductHolder::resetProductData_() {
00471   }
00472 
00473   bool NoProcessProductHolder::singleProduct_() const {
00474     return false;
00475   }
00476 
00477   void NoProcessProductHolder::setPrincipal_(Principal* principal) {
00478     throw Exception(errors::LogicError)
00479       << "NoProcessProductHolder::setPrincipal__() not implemented and should never be called.\n"
00480       << "Contact a Framework developer\n";
00481   }
00482 
00483   bool NoProcessProductHolder::onDemand_() const {
00484     throw Exception(errors::LogicError)
00485       << "NoProcessProductHolder::onDemand_() not implemented and should never be called.\n"
00486       << "Contact a Framework developer\n";
00487   }
00488 
00489   bool NoProcessProductHolder::productUnavailable_() const {
00490     throw Exception(errors::LogicError)
00491       << "NoProcessProductHolder::productUnavailable_() not implemented and should never be called.\n"
00492       << "Contact a Framework developer\n";
00493   }
00494 
00495   bool NoProcessProductHolder::productWasDeleted_() const {
00496     throw Exception(errors::LogicError)
00497       << "NoProcessProductHolder::productWasDeleted_() not implemented and should never be called.\n"
00498       << "Contact a Framework developer\n";
00499   }
00500 
00501   void NoProcessProductHolder::putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance) {
00502     throw Exception(errors::LogicError)
00503       << "NoProcessProductHolder::putProduct_() not implemented and should never be called.\n"
00504       << "Contact a Framework developer\n";
00505   }
00506 
00507   void NoProcessProductHolder::putProduct_(WrapperOwningHolder const& edp) const {
00508     throw Exception(errors::LogicError)
00509       << "NoProcessProductHolder::putProduct_() not implemented and should never be called.\n"
00510       << "Contact a Framework developer\n";
00511   }
00512 
00513   void NoProcessProductHolder::mergeProduct_(WrapperOwningHolder const&  edp, ProductProvenance& productProvenance) {
00514     throw Exception(errors::LogicError)
00515       << "NoProcessProductHolder::mergeProduct_() not implemented and should never be called.\n"
00516       << "Contact a Framework developer\n";
00517   }
00518 
00519   void NoProcessProductHolder::mergeProduct_(WrapperOwningHolder const& edp) const {
00520     throw Exception(errors::LogicError)
00521       << "NoProcessProductHolder::mergeProduct_() not implemented and should never be called.\n"
00522       << "Contact a Framework developer\n";
00523   }
00524 
00525   bool NoProcessProductHolder::putOrMergeProduct_() const {
00526     throw Exception(errors::LogicError)
00527       << "NoProcessProductHolder::putOrMergeProduct_() not implemented and should never be called.\n"
00528       << "Contact a Framework developer\n";
00529   }
00530 
00531   void NoProcessProductHolder::checkType_(WrapperOwningHolder const& prod) const {
00532     throw Exception(errors::LogicError)
00533       << "NoProcessProductHolder::checkType_() not implemented and should never be called.\n"
00534       << "Contact a Framework developer\n";
00535   }
00536 
00537   void NoProcessProductHolder::setProductDeleted_() {
00538     throw Exception(errors::LogicError)
00539       << "NoProcessProductHolder::setProductDeleted_() not implemented and should never be called.\n"
00540       << "Contact a Framework developer\n";
00541   }
00542 
00543   ConstBranchDescription const& NoProcessProductHolder::branchDescription_() const {
00544     throw Exception(errors::LogicError)
00545       << "NoProcessProductHolder::branchDescription_() not implemented and should never be called.\n"
00546       << "Contact a Framework developer\n";
00547   }
00548 
00549   void NoProcessProductHolder::resetBranchDescription_(boost::shared_ptr<ConstBranchDescription> bd) {
00550     throw Exception(errors::LogicError)
00551       << "NoProcessProductHolder::resetBranchDescription_() not implemented and should never be called.\n"
00552       << "Contact a Framework developer\n";
00553   }
00554 }