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