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