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 }