00001
00002
00003 #include <string>
00004 #include "DataFormats/Provenance/interface/ProductStatus.h"
00005 #include "FWCore/Framework/interface/Group.h"
00006 #include "FWCore/Utilities/interface/ReflexTools.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008
00009 using ROOT::Reflex::Type;
00010 using ROOT::Reflex::TypeTemplate;
00011
00012 namespace edm {
00013
00014 Group::Group() :
00015 product_(),
00016 branchDescription_(),
00017 entryInfo_(),
00018 prov_(),
00019 dropped_(false),
00020 onDemand_(false) {}
00021
00022 Group::Group(std::auto_ptr<EDProduct> edp, ConstBranchDescription const& bd, std::auto_ptr<EventEntryInfo> entryInfo) :
00023 product_(edp.release()),
00024 branchDescription_(new ConstBranchDescription(bd)),
00025 entryInfo_(entryInfo.release()),
00026 prov_(new Provenance(*branchDescription_, entryInfo_)),
00027 dropped_(!branchDescription_->present()),
00028 onDemand_(false) {
00029 }
00030
00031 Group::Group(ConstBranchDescription const& bd, std::auto_ptr<EventEntryInfo> entryInfo) :
00032 product_(),
00033 branchDescription_(new ConstBranchDescription(bd)),
00034 entryInfo_(entryInfo.release()),
00035 prov_(new Provenance(*branchDescription_, entryInfo_)),
00036 dropped_(!branchDescription_->present()),
00037 onDemand_(false) {
00038 }
00039
00040 Group::Group(std::auto_ptr<EDProduct> edp, ConstBranchDescription const& bd, boost::shared_ptr<EventEntryInfo> entryInfo) :
00041 product_(edp.release()),
00042 branchDescription_(new ConstBranchDescription(bd)),
00043 entryInfo_(entryInfo),
00044 prov_(new Provenance(*branchDescription_, entryInfo_)),
00045 dropped_(!branchDescription_->present()),
00046 onDemand_(false) {
00047 }
00048
00049 Group::Group(ConstBranchDescription const& bd, boost::shared_ptr<EventEntryInfo> entryInfo) :
00050 product_(),
00051 branchDescription_(new ConstBranchDescription(bd)),
00052 entryInfo_(entryInfo),
00053 prov_(new Provenance(*branchDescription_, entryInfo_)),
00054 dropped_(!branchDescription_->present()),
00055 onDemand_(false) {
00056 }
00057
00058 Group::Group(ConstBranchDescription const& bd, bool demand) :
00059 product_(),
00060 branchDescription_(new ConstBranchDescription(bd)),
00061 entryInfo_(),
00062 prov_(),
00063 dropped_(!branchDescription_->present()),
00064 onDemand_(demand) {
00065 }
00066
00067 Group::Group(ConstBranchDescription const& bd) :
00068 product_(),
00069 branchDescription_(new ConstBranchDescription(bd)),
00070 entryInfo_(),
00071 prov_(),
00072 dropped_(!branchDescription_->present()),
00073 onDemand_(false) {
00074 }
00075
00076 Group::~Group() {
00077 }
00078
00079 ProductStatus
00080 Group::status() const {
00081 if (dropped_) return productstatus::dropped();
00082 if (!entryInfo_) {
00083 if (product_) return product_->isPresent() ? productstatus::present() : productstatus::neverCreated();
00084 else return productstatus::unknown();
00085 }
00086 if (product_) {
00087
00088 product_->isPresent() ? entryInfo_->setPresent() : entryInfo_->setNotPresent();
00089 }
00090 return entryInfo_->productStatus();
00091 }
00092
00093 bool
00094 Group::onDemand() const {
00095 return onDemand_;
00096 }
00097
00098 bool
00099 Group::productUnavailable() const {
00100 if (onDemand()) return false;
00101 if (dropped_) return true;
00102 if (productstatus::unknown(status())) return false;
00103 return not productstatus::present(status());
00104
00105 }
00106
00107 bool
00108 Group::provenanceAvailable() const {
00109 if (onDemand()) return false;
00110 return true;
00111 }
00112
00113 void
00114 Group::setProduct(std::auto_ptr<EDProduct> prod) const {
00115 assert (product() == 0);
00116 product_.reset(prod.release());
00117 }
00118
00119 void
00120 Group::setProvenance(boost::shared_ptr<EventEntryInfo> entryInfo) const {
00121 entryInfo_ = entryInfo;
00122 if (entryInfo_) {
00123 prov_.reset(new Provenance(*branchDescription_, entryInfo_));
00124 } else {
00125 prov_.reset(new Provenance(*branchDescription_));
00126 }
00127 }
00128
00129 void
00130 Group::swap(Group& other) {
00131 std::swap(product_, other.product_);
00132 std::swap(branchDescription_, other.branchDescription_);
00133 std::swap(entryInfo_, other.entryInfo_);
00134 std::swap(prov_, other.prov_);
00135 std::swap(dropped_, other.dropped_);
00136 std::swap(onDemand_, other.onDemand_);
00137 }
00138
00139 void
00140 Group::replace(Group& g) {
00141 this->swap(g);
00142 }
00143
00144 Type
00145 Group::productType() const
00146 {
00147 return Type::ByTypeInfo(typeid(*product()));
00148 }
00149
00150 bool
00151 Group::isMatchingSequence(Type const& wantedElementType) const
00152 {
00153 Type value_type;
00154 bool is_sequence = is_sequence_wrapper(productType(), value_type);
00155
00156
00157 if (!is_sequence) return false;
00158
00159 Type elementType = value_type;
00160
00161 TypeTemplate valueTypeTemplate = value_type.TemplateFamily();
00162
00163 return
00164 is_sequence
00165 ? (elementType==wantedElementType ||
00166 elementType.HasBase(wantedElementType))
00167 : false;
00168 }
00169
00170 Provenance const *
00171 Group::provenance() const {
00172 if (!prov_.get()) {
00173 prov_.reset(new Provenance(*branchDescription_, entryInfo_));
00174 }
00175 return prov_.get();
00176 }
00177
00178 void
00179 Group::write(std::ostream& os) const
00180 {
00181
00182
00183 os << std::string("Group for product with ID: ")
00184 << entryInfo_->productID();
00185 }
00186
00187 void
00188 Group::mergeGroup(Group * newGroup) {
00189
00190 if (status() != newGroup->status()) {
00191 throw edm::Exception(edm::errors::Unknown, "Merging")
00192 << "Group::mergeGroup(), Trying to merge two run products or two lumi products.\n"
00193 << "The products have different creation status's.\n"
00194 << "For example \"present\" and \"notCreated\"\n"
00195 << "The Framework does not currently support this and probably\n"
00196 << "should not support this case.\n"
00197 << "Likely a problem exists in the producer that created these\n"
00198 << "products. If this problem cannot be reasonably resolved by\n"
00199 << "fixing the producer module, then contact the Framework development\n"
00200 << "group with details so we can discuss whether and how to support this\n"
00201 << "use case.\n"
00202 << "className = " << branchDescription_->className() << "\n"
00203 << "moduleLabel = " << moduleLabel() << "\n"
00204 << "instance = " << productInstanceName() << "\n"
00205 << "process = " << processName() << "\n";
00206 }
00207
00208 if (!entryInfo_) {
00209 return;
00210 }
00211
00212
00213
00214
00215 if (entryInfo_->moduleDescriptionID() != newGroup->entryInfo_->moduleDescriptionID()) {
00216 entryInfo_->setModuleDescriptionID(ModuleDescriptionID());
00217 }
00218
00219 if (!productUnavailable() && !newGroup->productUnavailable()) {
00220
00221 if (product_->isMergeable()) {
00222 product_->mergeProduct(newGroup->product_.get());
00223 }
00224 else if (product_->hasIsProductEqual()) {
00225
00226 if (!product_->isProductEqual(newGroup->product_.get())) {
00227 edm::LogWarning ("RunLumiMerging")
00228 << "Group::mergeGroup\n"
00229 << "Two run/lumi products for the same run/lumi which should be equal are not\n"
00230 << "Using the first, ignoring the second\n"
00231 << "className = " << branchDescription_->className() << "\n"
00232 << "moduleLabel = " << moduleLabel() << "\n"
00233 << "instance = " << productInstanceName() << "\n"
00234 << "process = " << processName() << "\n";
00235 }
00236 }
00237 else {
00238 edm::LogWarning ("RunLumiMerging")
00239 << "Group::mergeGroup\n"
00240 << "Run/lumi product has neither a mergeProduct nor isProductEqual function\n"
00241 << "Using the first, ignoring the second in merge\n"
00242 << "className = " << branchDescription_->className() << "\n"
00243 << "moduleLabel = " << moduleLabel() << "\n"
00244 << "instance = " << productInstanceName() << "\n"
00245 << "process = " << processName() << "\n";
00246 }
00247 }
00248 }
00249 }