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