CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/FWCore/Framework/src/Group.cc

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------
00002 ----------------------------------------------------------------------*/
00003 #include "DataFormats/Provenance/interface/ProductStatus.h"
00004 #include "FWCore/Framework/interface/Group.h"
00005 #include "FWCore/Utilities/interface/ReflexTools.h"
00006 #include "FWCore/Utilities/interface/TypeID.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 
00009 using Reflex::Type;
00010 using Reflex::TypeTemplate;
00011 
00012 namespace edm {
00013 
00014   Group::Group() {}
00015 
00016   Group::~Group() {}
00017   InputGroup::~InputGroup() {}
00018   ProducedGroup::~ProducedGroup() {}
00019   ScheduledGroup::~ScheduledGroup() {}
00020   UnscheduledGroup::~UnscheduledGroup() {}
00021   SourceGroup::~SourceGroup() {}
00022 
00023   void
00024   ProducedGroup::putProduct_(
00025         std::auto_ptr<EDProduct> edp,
00026         boost::shared_ptr<ProductProvenance> productProvenance) {
00027     if (product()) {
00028       throw edm::Exception(errors::InsertFailure)
00029           << "Attempt to insert more than one product on branch " << groupData().branchDescription()->branchName() << "\n";
00030     }
00031     assert(branchDescription().produced());
00032     assert(edp.get() != 0);
00033     assert(!provenance()->productProvenanceResolved());
00034     assert(status() != Present);
00035     assert(status() != Uninitialized);
00036     setProductProvenance(productProvenance);
00037     assert(provenance()->productProvenanceResolved());
00038     groupData().product_.reset(edp.release());  // Group takes ownership
00039     status_() = Present;
00040   }
00041 
00042   void
00043   ProducedGroup::mergeProduct_(
00044         std::auto_ptr<EDProduct> edp,
00045         boost::shared_ptr<ProductProvenance> productProvenance) {
00046     assert(provenance()->productProvenanceResolved());
00047     assert(status() == Present);
00048     assert (productProvenancePtr()->productStatus() == productProvenance->productStatus());
00049     productProvenancePtr() = productProvenance;
00050     mergeTheProduct(edp);
00051   }
00052 
00053   bool
00054   ProducedGroup::putOrMergeProduct_() const {
00055     return productUnavailable();
00056   }
00057 
00058   void
00059   ProducedGroup::mergeProduct_(std::auto_ptr<EDProduct> edp) const {
00060     assert(0);
00061   }
00062 
00063   void
00064   ProducedGroup::putProduct_(std::auto_ptr<EDProduct> edp) const {
00065     assert(0);
00066   }
00067 
00068   void
00069   InputGroup::putProduct_(
00070         std::auto_ptr<EDProduct> edp,
00071         boost::shared_ptr<ProductProvenance> productProvenance) {
00072     assert(!product());
00073     assert(!provenance()->productProvenanceResolved());
00074     setProductProvenance(productProvenance);
00075     assert(provenance()->productProvenanceResolved());
00076     setProduct(edp);
00077   }
00078 
00079   void
00080   InputGroup::mergeProduct_(
00081         std::auto_ptr<EDProduct> edp,
00082         boost::shared_ptr<ProductProvenance> productProvenance) {
00083     assert(0);
00084   }
00085 
00086   void
00087   InputGroup::mergeProduct_(std::auto_ptr<EDProduct> edp) const {
00088     mergeTheProduct(edp);
00089   }
00090 
00091   bool
00092   InputGroup::putOrMergeProduct_() const {
00093     return (!product());
00094   }
00095 
00096   void
00097   InputGroup::putProduct_(std::auto_ptr<EDProduct> edp) const {
00098     assert(!product());
00099     setProduct(edp);
00100   }
00101 
00102   void
00103   Group::mergeTheProduct(std::auto_ptr<EDProduct> edp) const {
00104     if (product()->isMergeable()) {
00105       product()->mergeProduct(edp.get());
00106     } else if (product()->hasIsProductEqual()) {
00107       if (!product()->isProductEqual(edp.get())) {
00108         LogError("RunLumiMerging")
00109               << "Group::mergeGroup\n"
00110               << "Two run/lumi products for the same run/lumi which should be equal are not\n"
00111               << "Using the first, ignoring the second\n"
00112               << "className = " << branchDescription().className() << "\n"
00113               << "moduleLabel = " << moduleLabel() << "\n"
00114               << "instance = " << productInstanceName() << "\n"
00115               << "process = " << processName() << "\n";
00116       }
00117     } else {
00118       LogWarning("RunLumiMerging")
00119           << "Group::mergeGroup\n"
00120           << "Run/lumi product has neither a mergeProduct nor isProductEqual function\n"
00121           << "Using the first, ignoring the second in merge\n"
00122           << "className = " << branchDescription().className() << "\n"
00123           << "moduleLabel = " << moduleLabel() << "\n"
00124           << "instance = " << productInstanceName() << "\n"
00125           << "process = " << processName() << "\n";
00126     }
00127   }
00128 
00129   void
00130   GroupData::checkType(EDProduct const& prod) const {
00131     // Check if the types match.
00132     TypeID typeID(prod.dynamicTypeInfo());
00133     if (typeID != branchDescription()->typeID()) {
00134       // Types do not match.
00135       throw edm::Exception(errors::EventCorruption)
00136           << "Product on branch " << branchDescription()->branchName() << " is of wrong type.\n"
00137           << "It is supposed to be of type " << branchDescription()->className() << ".\n"
00138           << "It is actually of type " << typeID.className() << ".\n";
00139     }
00140   }
00141 
00142   void
00143   InputGroup::setProduct(std::auto_ptr<EDProduct> prod) const {
00144     assert (!product());
00145     if (prod.get() == 0 || !prod->isPresent()) {
00146       setProductUnavailable();
00147     }
00148     groupData().product_.reset(prod.release());  // Group takes ownership
00149   }
00150 
00151   void
00152   Group::setProductProvenance(boost::shared_ptr<ProductProvenance> prov) const {
00153     groupData().prov_.setProductProvenance(prov);
00154   }
00155 
00156   // This routine returns true if it is known that currently there is no real product.
00157   // If there is a real product, it returns false.
00158   // If it is not known if there is a real product, it returns false.
00159   bool
00160   InputGroup::productUnavailable_() const {
00161     if (productIsUnavailable()) {
00162       return true;
00163     }
00164     // If there is a product, we know if it is real or a dummy.
00165     if (product()) {
00166       bool unavailable = !(product()->isPresent());
00167       if (unavailable) {
00168         setProductUnavailable();
00169       }
00170       return unavailable;
00171     }
00172     return false;
00173   }
00174 
00175   // This routine returns true if it is known that currently there is no real product.
00176   // If there is a real product, it returns false.
00177   // If it is not known if there is a real product, it returns false.
00178   bool
00179   ProducedGroup::productUnavailable_() const {
00180     // If unscheduled production, the product is potentially available.
00181     if (onDemand()) return false;
00182     // The product is available if and only if a product has been put.
00183     bool unavailable = !(product() && product()->isPresent());
00184     assert (!productstatus::presenceUnknown(status()));
00185     assert(unavailable == productstatus::notPresent(status()));
00186     return unavailable;
00187   }
00188 
00189   bool
00190   Group::provenanceAvailable() const {
00191     // If this product is from a the current process,
00192     // the provenance is available if and only if a product has been put.
00193     if (branchDescription().produced()) {
00194       return product() && product()->isPresent();
00195     }
00196     // If this product is from a prior process, the provenance is available,
00197     // although the per event part may have been dropped.
00198     return true;
00199   }
00200 
00201   Type
00202   Group::productType() const {
00203     return Type::ByTypeInfo(typeid(*product()));
00204   }
00205 
00206   bool
00207   Group::isMatchingSequence(Type const& wantedElementType) const {
00208     Type value_type;
00209     bool is_sequence = is_sequence_wrapper(productType(), value_type);
00210 
00211     // If our product is not a sequence, we can't match...
00212     if (!is_sequence) return false;
00213 
00214     Type elementType = value_type; // this is not true for RefVector...
00215 
00216     TypeTemplate valueTypeTemplate = value_type.TemplateFamily();
00217 
00218     return (elementType==wantedElementType ||
00219             elementType.HasBase(wantedElementType));
00220   }
00221 
00222   void
00223   Group::setProvenance(boost::shared_ptr<BranchMapper> mapper, ProductID const& pid) {
00224     //assert(!groupData().prov_);
00225     groupData().prov_.setProductID(pid);
00226     groupData().prov_.setStore(mapper);
00227   }
00228 
00229   void
00230   Group::setProvenance(boost::shared_ptr<BranchMapper> mapper) {
00231     groupData().prov_.setStore(mapper);
00232   }
00233 
00234   Provenance*
00235   Group::provenance() const {
00236     return &(groupData().prov_);
00237   }
00238 
00239   void
00240   Group::write(std::ostream& os) const {
00241     // This is grossly inadequate. It is also not critical for the
00242     // first pass.
00243     os << std::string("Group for product with ID: ")
00244        << productID();
00245   }
00246 }