Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MiniAOD RNTuple conversion #6

Open
14 of 34 tasks
nsmith- opened this issue Nov 17, 2023 · 17 comments
Open
14 of 34 tasks

MiniAOD RNTuple conversion #6

nsmith- opened this issue Nov 17, 2023 · 17 comments

Comments

@nsmith-
Copy link
Collaborator

nsmith- commented Nov 17, 2023

In CMSSW_14_0_0_pre0_ROOT630 the following MiniAOD (SIM) branches are not interpretable by RNTuple

Muon hits

In edm::RangeMap<CSCDetId,edm::OwnVector<CSCSegment,edm::ClonePolicy<CSCSegment> >,edm::ClonePolicy<CSCSegment> > :
    In edm::OwnVector<CSCSegment,edm::ClonePolicy<CSCSegment> > collection_:
        In vector<CSCSegment*> data_:
            In CSCSegment* :
                    RException: RField: no I/O support for type CSCSegment* (no dictionary to recurse)
    In map<CSCDetId,pair<unsigned int,unsigned int> > map_:
            RException: map<CSCDetId,pair<unsigned int,unsigned int> > is not supported (cannot recurse maps safely?)
In edm::RangeMap<DTChamberId,edm::OwnVector<DTRecSegment4D,edm::ClonePolicy<DTRecSegment4D> >,edm::ClonePolicy<DTRecSegment4D> > :
    In edm::OwnVector<DTRecSegment4D,edm::ClonePolicy<DTRecSegment4D> > collection_:
        In vector<DTRecSegment4D*> data_:
            In DTRecSegment4D* :
                    RException: RField: no I/O support for type DTRecSegment4D* (no dictionary to recurse)
    In map<DTChamberId,pair<unsigned int,unsigned int> > map_:
            RException: map<DTChamberId,pair<unsigned int,unsigned int> > is not supported (cannot recurse maps safely?)

From cms-sw#42734 (comment) the edm::OwnVector can be replaced with std::vector

Muon inner track data

In edmNew::DetSetVector<SiPixelCluster> :
    In vector<edmNew::dstvdetails::DetSetVectorTrans::Item> m_ids:
        In edmNew::dstvdetails::DetSetVectorTrans::Item :
            In atomic<int> offset:
                    RException: atomic<int> is not supported
In edmNew::DetSetVector<SiStripCluster> :
    In vector<edmNew::dstvdetails::DetSetVectorTrans::Item> m_ids:
        In edmNew::dstvdetails::DetSetVectorTrans::Item :
            In atomic<int> offset:
                    RException: atomic<int> is not supported

These are already supported in ROOT master.

In edm::OwnVector<TrackingRecHit,edm::ClonePolicy<TrackingRecHit> > :
    In vector<TrackingRecHit*> data_:
        In TrackingRecHit* :
                RException: RField: no I/O support for type TrackingRecHit* (no dictionary to recurse)

From cms-sw#42734 (comment) the class is using polymorphism

  • Write EDProducer to handle edm::OwnVector<TrackingRecHit> data products

This is labeled as slimmedMuonTrackExtras, so cms-sw#42734 (comment) may be relevant for testing the muon tracks can be re-fitted from MiniAOD written after the migration.

oniaPhotonCandidates

In vector<pat::CompositeCandidate> > :
    In pat::CompositeCandidate>  :
        In vector<pat::TriggerObjectStandAlone> triggerObjectMatchesEmbedded_ (base pat::PATObject<reco::CompositeCandidate>):
            In pat::TriggerObjectStandAlone :
                In edm::RefToBase<reco::Candidate> refToOrig_ (base pat::TriggerObject):
                        RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Candidate>* (unchecked RResult access!) (no children failed)
        In edm::OwnVector<pat::UserData,edm::ClonePolicy<pat::UserData> > userDataObjects_ (base pat::PATObject<reco::CompositeCandidate>):
            In vector<pat::UserData*> data_:
                In pat::UserData* :
                        RException: RField: no I/O support for type pat::UserData* (no dictionary to recurse)

This is the collection patCompositeCandidates_oniaPhotonCandidates_conversions_PAT.

Electrons

In vector<pat::Electron> > :
    In pat::Electron>  :
        In vector<reco::PFCandidate> pfCandidate_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<pair<pat::IsolationKeys,reco::IsoDeposit> > isoDeposits_ (base pat::Lepton<reco::GsfElectron>):
            In pair<pat::IsolationKeys,reco::IsoDeposit>  :
                In reco::IsoDeposit second:
                    In multimap<reco::isodeposit::Direction::Distance,float> theDeposits:
                            RException: multimap<reco::isodeposit::Direction::Distance,float> is not supported (cannot recurse maps safely?)
        In reco::GsfElectron::ConversionRejection conversionRejection_ (base reco::GsfElectron):
            In edm::RefToBase<reco::Track> partner:
                    RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Track>* (unchecked RResult access!) (no children failed)

Jets

In vector<pat::Jet> > :
    In pat::Jet>  :
        In vector<reco::PFCandidate> pfCandidates_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In edm::OwnVector<reco::BaseTagInfo,edm::ClonePolicy<reco::BaseTagInfo> > tagInfos_:
            In vector<reco::BaseTagInfo*> data_:
                In reco::BaseTagInfo* :
                        RException: RField: no I/O support for type reco::BaseTagInfo* (no dictionary to recurse)
        In vector<reco::JPTJet::Specific> specificJPT_:
            In reco::JPTJet::Specific :
                In edm::RefToBase<reco::Jet> theCaloJetRef:
                        RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Jet>* (unchecked RResult access!) (no children failed)
        In vector<pat::TriggerObjectStandAlone> triggerObjectMatchesEmbedded_ (base pat::PATObject<reco::Jet>):
            In pat::TriggerObjectStandAlone :
                In edm::RefToBase<reco::Candidate> refToOrig_ (base pat::TriggerObject):
                        RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Candidate>* (unchecked RResult access!) (no children failed)
        In edm::OwnVector<pat::UserData,edm::ClonePolicy<pat::UserData> > userDataObjects_ (base pat::PATObject<reco::Jet>):
            In vector<pat::UserData*> data_:
                In pat::UserData* :
                        RException: RField: no I/O support for type pat::UserData* (no dictionary to recurse)

MET

In vector<pat::MET> > :
    In pat::MET>  :
        In vector<pat::TriggerObjectStandAlone> triggerObjectMatchesEmbedded_ (base pat::PATObject<reco::MET>):
            In pat::TriggerObjectStandAlone :
                In edm::RefToBase<reco::Candidate> refToOrig_ (base pat::TriggerObject):
                        RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Candidate>* (unchecked RResult access!) (no children failed)
        In edm::OwnVector<pat::UserData,edm::ClonePolicy<pat::UserData> > userDataObjects_ (base pat::PATObject<reco::MET>):
            In vector<pat::UserData*> data_:
                In pat::UserData* :
                        RException: RField: no I/O support for type pat::UserData* (no dictionary to recurse)

Muons

In vector<pat::Muon> > :
    In pat::Muon>  :
        In vector<reco::PFCandidate> pfCandidate_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<pair<pat::IsolationKeys,reco::IsoDeposit> > isoDeposits_ (base pat::Lepton<reco::Muon>):
            In pair<pat::IsolationKeys,reco::IsoDeposit>  :
                In reco::IsoDeposit second:
                    In multimap<reco::isodeposit::Direction::Distance,float> theDeposits:
                            RException: multimap<reco::isodeposit::Direction::Distance,float> is not supported (cannot recurse maps safely?)
        In map<reco::Muon::MuonTrackType,edm::Ref<vector<reco::Track>,reco::Track,edm::refhelper::FindUsingAdvance<vector<reco::Track>,reco::Track> > > refittedTrackMap_ (base reco::Muon):
                RException: map<reco::Muon::MuonTrackType,edm::Ref<vector<reco::Track>,reco::Track,edm::refhelper::FindUsingAdvance<vector<reco::Track>,reco::Track> > > is not supported (cannot recurse maps safely?)

Photons

In vector<pat::Photon> > :
    In pat::Photon>  :
        In vector<pair<pat::IsolationKeys,reco::IsoDeposit> > isoDeposits_:
            In pair<pat::IsolationKeys,reco::IsoDeposit>  :
                In reco::IsoDeposit second:
                    In multimap<reco::isodeposit::Direction::Distance,float> theDeposits:
                            RException: multimap<reco::isodeposit::Direction::Distance,float> is not supported (cannot recurse maps safely?)
        In vector<pat::TriggerObjectStandAlone> triggerObjectMatchesEmbedded_ (base pat::PATObject<reco::Photon>):
            In pat::TriggerObjectStandAlone :
                In edm::RefToBase<reco::Candidate> refToOrig_ (base pat::TriggerObject):
                        RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Candidate>* (unchecked RResult access!) (no children failed)
        In edm::OwnVector<pat::UserData,edm::ClonePolicy<pat::UserData> > userDataObjects_ (base pat::PATObject<reco::Photon>):
            In vector<pat::UserData*> data_:
                In pat::UserData* :
                        RException: RField: no I/O support for type pat::UserData* (no dictionary to recurse)

Taus

In vector<pat::Tau> > :
    In pat::Tau>  :
        In vector<reco::PFCandidate> leadPFCand_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> leadPFChargedHadrCand_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> leadPFNeutralCand_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> signalPFCands_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> signalPFChargedHadrCands_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> signalPFNeutralHadrCands_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> signalPFGammaCands_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> isolationPFCands_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> isolationPFChargedHadrCands_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> isolationPFNeutralHadrCands_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<reco::PFCandidate> isolationPFGammaCands_:
            In reco::PFCandidate :
                In vector<ULong64_t> refsInfo_:
                    In ULong64_t :
                            RException: RField: no I/O support for type ULong64_t (no dictionary to recurse)
                In edm::OwnVector<reco::Candidate,edm::ClonePolicy<reco::Candidate> > dau (base reco::CompositeCandidate):
                    In vector<reco::Candidate*> data_:
                        In reco::Candidate* :
                                RException: RField: no I/O support for type reco::Candidate* (no dictionary to recurse)
        In vector<pat::tau::TauPFSpecific> pfSpecific_:
            In pat::tau::TauPFSpecific :
                In edm::RefToBase<reco::Jet> pfJetRef_:
                        RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Jet>* (unchecked RResult access!) (no children failed)
        In vector<pair<pat::IsolationKeys,reco::IsoDeposit> > isoDeposits_ (base pat::Lepton<reco::BaseTau>):
            In pair<pat::IsolationKeys,reco::IsoDeposit>  :
                In reco::IsoDeposit second:
                    In multimap<reco::isodeposit::Direction::Distance,float> theDeposits:
                            RException: multimap<reco::isodeposit::Direction::Distance,float> is not supported (cannot recurse maps safely?)

Trigger objects

In vector<pat::TriggerObjectStandAlone> > :
    In pat::TriggerObjectStandAlone>  :
        In edm::RefToBase<reco::Candidate> refToOrig_ (base pat::TriggerObject):
                RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Candidate>* (unchecked RResult access!) (no children failed)

Jet tagInfos

In edm::OwnVector<reco::BaseTagInfo,edm::ClonePolicy<reco::BaseTagInfo> > > :
    In vector<reco::BaseTagInfo*> data_:
        In reco::BaseTagInfo* :
                RException: RField: no I/O support for type reco::BaseTagInfo* (no dictionary to recurse)

This is recoBaseTagInfosOwned_slimmedJetsPuppi_tagInfos_PAT. From cms-sw#42734 (comment) the class is using polymorphism.

  • Confirm this is always empty, and drop collection from MINIAOD data tier

Conversions

In vector<reco::Conversion> > :
    In reco::Conversion>  :
        In vector<edm::RefToBase<reco::Track> > trackToBaseRefs_:
            In edm::RefToBase<reco::Track>  :
                    RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Track>* (unchecked RResult access!) (no children failed)
        In reco::Vertex theConversionVertex_:
            In vector<edm::RefToBase<reco::Track> > tracks_:
                In edm::RefToBase<reco::Track>  :
                        RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Track>* (unchecked RResult access!) (no children failed)
            In reco::Vertex::(unnamed) dimension:
                (TypeError) Could not instantiate MakeField<reco::Vertex::(unnamed)>: (no dictionary to recurse)
            In reco::Vertex::(unnamed) dimension4D:
                (TypeError) Could not instantiate MakeField<reco::Vertex::(unnamed)>: (no dictionary to recurse)
            In reco::Vertex::(unnamed) size:
                (TypeError) Could not instantiate MakeField<reco::Vertex::(unnamed)>: (no dictionary to recurse)
            In reco::Vertex::(unnamed) size4D:
                (TypeError) Could not instantiate MakeField<reco::Vertex::(unnamed)>: (no dictionary to recurse)

TODO: is the poor-mans constexpr here really being persisted?

  • RefToBase to Ptr conversion for vector<edm::RefToBase<reco::Track> > tracks_

More muon track data

In vector<reco::TrackExtra> > :
    In reco::TrackExtra>  :
        In edm::RefToBase<TrajectorySeed> seedRef_:
                RException: Field holder_ has unknown type edm::reftobase::BaseHolder<TrajectorySeed>* (unchecked RResult access!) (no children failed)
        In reco::TrackExtra::(unnamed) dimension:
            (TypeError) Could not instantiate MakeField<reco::TrackExtra::(unnamed)>: (no dictionary to recurse)
        In reco::TrackExtra::(unnamed) covarianceSize:
            (TypeError) Could not instantiate MakeField<reco::TrackExtra::(unnamed)>: (no dictionary to recurse)

TODO: is the poor-mans constexpr here really being persisted?

  • RefToBase to Ptr conversion for edm::RefToBase<TrajectorySeed> seedRef_

Vertices

In vector<reco::Vertex> > :
    In reco::Vertex>  :
        In vector<edm::RefToBase<reco::Track> > tracks_:
            In edm::RefToBase<reco::Track>  :
                    RException: Field holder_ has unknown type edm::reftobase::BaseHolder<reco::Track>* (unchecked RResult access!) (no children failed)
        In reco::Vertex::(unnamed) dimension:
            (TypeError) Could not instantiate MakeField<reco::Vertex::(unnamed)>: (no dictionary to recurse)
        In reco::Vertex::(unnamed) dimension4D:
            (TypeError) Could not instantiate MakeField<reco::Vertex::(unnamed)>: (no dictionary to recurse)
        In reco::Vertex::(unnamed) size:
            (TypeError) Could not instantiate MakeField<reco::Vertex::(unnamed)>: (no dictionary to recurse)
        In reco::Vertex::(unnamed) size4D:
            (TypeError) Could not instantiate MakeField<reco::Vertex::(unnamed)>: (no dictionary to recurse)

TODO: is the poor-mans constexpr here really being persisted?

  • RefToBase to Ptr conversion for vector<edm::RefToBase<reco::Track> > tracks_

@Dr15Jones @makortel may be interested in this

@nsmith-
Copy link
Collaborator Author

nsmith- commented Nov 17, 2023

The list of members to migrate was produced using this very hacky script

import ROOT

exc_cache = {}

def safe_members(tclass):
    for mem in tclass.GetListOfDataMembers():
        if not mem.IsPersistent():
            continue
        mclass = ROOT.TClass.GetClass(mem.GetTypeName())
        if not mclass:
            yield mem
            continue
        if not mclass.HasDefaultConstructor():
            continue
        if mclass.ClassProperty() & ROOT.EClassProperty.kClassIsAbstract:
            continue
        yield mem

def printIndent(indent: int, msg: str):
    print(" "*indent + msg)


def findbad(classname, indent=0, member_name=""):
    if classname in exc_cache:
        # it seems that RNTuple slowly goes mad?
        msg = exc_cache[classname]
    else:
        try:
            model = ROOT.Experimental.RNTupleModel.Create()
            model.MakeField[classname]("test")
            return True
        except ROOT.Experimental.RException as ex:
            msg = str(ex).split("\n")[2]
            exc_cache[classname] = msg
        except TypeError as ex:
            # some weird state switch?
            msg = "(TypeError) " + str(ex).split("\n")[0]
        except ValueError as ex:
            printIndent(indent, f"ValueError for {classname} {member_name}, quitting")
            raise ex
        finally:
            del model
    printIndent(indent, f"In {classname} {member_name}:")
    tclass = ROOT.TClass.GetClass(classname)
    if not tclass:
        printIndent(indent+4, f"{msg} (no dictionary to recurse)")
        return False
    # https://github.com/root-project/root/blob/v6-30-01/tree/ntuple/v7/src/RField.cxx#L351
    if classname.startswith("vector<"):
        findbad(classname[classname.find("<")+1:classname.rfind(">")], indent + 4, "")
    elif classname.startswith("multimap<") or classname.startswith("map<"):
        printIndent(indent+4, f"{msg} (cannot recurse maps safely?)")
    elif classname.startswith("atomic<"):
        printIndent(indent+4, f"{msg}")
    else:
        good = True
        for mem in safe_members(tclass):
            good &= findbad(mem.GetTypeName(), indent + 4, mem.GetName())
        for base in tclass.GetListOfBases():
            bclass = ROOT.TClass.GetClass(base.GetName())
            for mem in safe_members(bclass):
                good &= findbad(mem.GetTypeName(), indent + 4, mem.GetName() + f" (base {base.GetName()})")
        if good:
            printIndent(indent+4, f"{msg} (no children failed)")
    return False


badproducts_mini = [
    "edm::RangeMap<CSCDetId,edm::OwnVector<CSCSegment,edm::ClonePolicy<CSCSegment> >,edm::ClonePolicy<CSCSegment> >",
    "edm::RangeMap<DTChamberId,edm::OwnVector<DTRecSegment4D,edm::ClonePolicy<DTRecSegment4D> >,edm::ClonePolicy<DTRecSegment4D> >",
    "edmNew::DetSetVector<SiPixelCluster>",
    "edmNew::DetSetVector<SiStripCluster>",
    "edm::OwnVector<TrackingRecHit,edm::ClonePolicy<TrackingRecHit> >",
    "vector<pat::CompositeCandidate> >",
    "vector<pat::Electron> >",
    "vector<pat::Jet> >",
    "vector<pat::MET> >",
    "vector<pat::Muon> >",
    "vector<pat::Photon> >",
    "vector<pat::Tau> >",
    "vector<pat::TriggerObjectStandAlone> >",
    "edm::OwnVector<reco::BaseTagInfo,edm::ClonePolicy<reco::BaseTagInfo> > >",
    "vector<reco::Conversion> >",
    "vector<reco::TrackExtra> >",
    "vector<reco::Vertex> >",
]
for p in badproducts_mini:
    findbad(p)

It is definitely not working fully correctly, as all pat objects should have the userDataObjects_ problem.

@Dr15Jones
Copy link

So for the miniaod file /uscms_data/d3/ncsmith/cms-rntuple-work/data/ul17ttsemi_miniaod.root, none of the std::vector<pat::Jet> branches have any entries for tagInfos_ in any of the jets.

Looking at the class edm::BaseTagInfo and its inheriting classes, it would probably be a good first try to replace edm::OwnVector<edm::BaseTagInfo> with std::vector<edm::ShallowTagInfo> and just assume none of the classes that inherit from edm::BaseTagInfo that then add additional information (which can only be accessed by dynamic cast) are stored in any production jobs.

@Dr15Jones
Copy link

Scratch what I wrote about pat::Jet and edm::BaseTagInfo. The pat::Jet has explicit knowledge of some of the types inheriting from edm::BaseTagInfo and will convert them behind the scene when requested. Therefore, to preserve the interface requires we have an std::vector per known type.

@Dr15Jones
Copy link

Dr15Jones commented Nov 20, 2023

More info on the use of edm::BaseTagInfo in pat::Jet. The member tagInfos_ which is of type edm::OwnVector<reco::BaseTagInfo> has no methods in the class to be able to set the value. It appears to just exist to read really-really-really old pat::Jet from storage. It looks like we haven't been able to add stuff to tagInfos_ since 2010

cms-sw@001b932.

I say we nuke it from orbit, as it is the only way to be sure.

@nsmith-
Copy link
Collaborator Author

nsmith- commented Nov 21, 2023

I updated the scan script to recurse through subclasses, and other than showing that (as expected) all pat::Object<...> have the userDataObjects_ issue, also there is a new map in muons,

        In map<reco::Muon::MuonTrackType,edm::Ref<vector<reco::Track>,reco::Track,edm::refhelper::FindUsingAdvance<vector<reco::Track>,reco::Track> > > refittedTrackMap_ (base reco::Muon):
                RException: map<reco::Muon::MuonTrackType,edm::Ref<vector<reco::Track>,reco::Track,edm::refhelper::FindUsingAdvance<vector<reco::Track>,reco::Track> > > is not supported (cannot recurse maps safely?)

which I added above as well

@Dr15Jones
Copy link

So I did a 'hack' where I kept the type as edm::RangeMap<..., edm::OwnVector<...>> but internally it swapped the edm::OwnVector<T> for a std::vector<T>. I used an IO rule to copy the data from the old edm::OwnVector to the new std::vector and that worked.

The problem is running @nsmith- 's python program that tests RNTuple compatibility. When I run that in my new area, I get the failure

In edm::RangeMap<CSCDetId,edm::OwnVector<CSCSegment,edm::ClonePolicy<CSCSegment> >,edm::ClonePolicy<CSCSegment> > :
    In vector<CSCSegment> collection_:
        In CSCSegment :
            In vector<CSCRecHit2D> theCSCRecHits:
                In CSCRecHit2D :
Traceback (most recent call last):
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 90, in <module>
    findbad(p)
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 58, in findbad
    good &= findbad(mem.GetTypeName(), indent + 4, mem.GetName())
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 50, in findbad
    findbad(classname[classname.find("<")+1:classname.rfind(">")], indent + 4, "")
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 58, in findbad
    good &= findbad(mem.GetTypeName(), indent + 4, mem.GetName())
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 50, in findbad
    findbad(classname[classname.find("<")+1:classname.rfind(">")], indent + 4, "")
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 58, in findbad
    good &= findbad(mem.GetTypeName(), indent + 4, mem.GetName())
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 30, in findbad
    model.MakeField[classname]("test")
cppyy.gbl.std.runtime_error: Could not instantiate MakeField<CSCRecHit2D::SharedInputType>:
  shared_ptr<CSCRecHit2D::SharedInputType> ROOT::Experimental::RNTupleModel::MakeField(basic_string_view<char,char_traits<char> > fieldName) =>
    runtime_error: RField: no I/O support for type CSCRecHit2D::SharedInputType

Where CSCRecHit2D::SharedInputType is an enum in the class CSCRecHit2D. The enum is only used in member functions and is NOT used as member data.

@pcanal does RNTuple have problems with enums in classes?

@Dr15Jones
Copy link

@pcanal I see another failure

In edm::RangeMap<DTChamberId,edm::OwnVector<DTRecSegment4D,edm::ClonePolicy<DTRecSegment4D> >,edm::ClonePolicy<DTRecSegment4D> > :
    In vector<DTRecSegment4D> collection_:
        In DTRecSegment4D :
input_line_76:7:45: error: 'Projection' is a private member of 'DTRecSegment4D'
      new (ret) (shared_ptr<DTRecSegment4D::Projection>) (((ROOT::Experimental::RNTupleModel*)obj)->MakeField<DTRecSegment4D::Projection>(*(basic_string_view<char,char_traits<char> >*)args[0]));
                                            ^
/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/DataFormats/DTRecHit/interface/DTRecSegment4D.h:115:8: note: declared private here
  enum Projection { full, phi, Z, none };
       ^
input_line_76:7:127: error: 'Projection' is a private member of 'DTRecSegment4D'
      new (ret) (shared_ptr<DTRecSegment4D::Projection>) (((ROOT::Experimental::RNTupleModel*)obj)->MakeField<DTRecSegment4D::Projection>(*(basic_string_view<char,char_traits<char> >*)args[0]));
                                                                                                                              ^
/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/DataFormats/DTRecHit/interface/DTRecSegment4D.h:115:8: note: declared private here
  enum Projection { full, phi, Z, none };
       ^
input_line_76:11:82: error: 'Projection' is a private member of 'DTRecSegment4D'
      (void)(((ROOT::Experimental::RNTupleModel*)obj)->MakeField<DTRecSegment4D::Projection>(*(basic_string_view<char,char_traits<char> >*)args[0]));
                                                                                 ^
/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/DataFormats/DTRecHit/interface/DTRecSegment4D.h:115:8: note: declared private here
  enum Projection { full, phi, Z, none };
       ^
            ValueError for DTRecSegment4D::Projection theProjection, quitting
Traceback (most recent call last):
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 90, in <module>
    findbad(p)
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 58, in findbad
    good &= findbad(mem.GetTypeName(), indent + 4, mem.GetName())
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 50, in findbad
    findbad(classname[classname.find("<")+1:classname.rfind(">")], indent + 4, "")
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 58, in findbad
    good &= findbad(mem.GetTypeName(), indent + 4, mem.GetName())
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 40, in findbad
    raise ex
  File "/uscms_data/d2/cdj/build/temp/rntuple/CMSSW_14_0_0_pre0/src/bad_members.py", line 30, in findbad
    model.MakeField[classname]("test")
ValueError: Could not instantiate MakeField<DTRecSegment4D::Projection>:
  shared_ptr<DTRecSegment4D::Projection> ROOT::Experimental::RNTupleModel::MakeField(basic_string_view<char,char_traits<char> > fieldName) =>
    ValueError: nullptr result where temporary expected

@Dr15Jones
Copy link

So I added entries to classes_def.xml to explicitly force the creating of dictionaries for the enum types, but the build failed with

Warning: Unused class rule: CSCRecHit2D::SharedInputType
Warning: Unused class rule: DTRecSegment4D::Projection

@Dr15Jones
Copy link

I tried switching DTRecSegment4D::Projection to an enum class but that didn't help (even though DTRecSegment4D has a member data of type Projection).

So it seems Nick's script which tries to figure out why RNTuple rejects the type says that RNTuple is requiring a dictionary for an enum but genreflex refuses to generate one.

@nsmith-
Copy link
Collaborator Author

nsmith- commented Jan 16, 2024

I would guess that there is an issue with how my script works, in that if a class cannot be made into an RNTuple field, and it contains items that RNTuple would have skipped over, it would claim those are the problem even when they are (probably) not actually serialized. I don't know if I'm duplicating the logic correctly, nor did I really want to duplicate it!

What happens if you just try

model = ROOT.Experimental.RNTupleModel.Create()
model.MakeField["CSCRecHit2D"]("test")

?

@Dr15Jones
Copy link

What happens if you just try

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
cppyy.gbl.ROOT.Experimental.RException: Could not instantiate MakeField<CSCRecHit2D>:
  shared_ptr<CSCRecHit2D> ROOT::Experimental::RNTupleModel::MakeField(basic_string_view<char,char_traits<char> > fieldName) =>
    RException: Field valid has unknown type TrackingRecHit::Type (unchecked RResult access!)
At:
  static ROOT::Experimental::RResult<std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> > ROOT::Experimental::Detail::RFieldBase::Create(const std::string&, const std::string&) [/data/cmsbld/jenkins/workspace/auto-builds/CMSSW_13_3_0_pre5-el8_amd64_gcc12/build/CMSSW_13_3_0_pre5-build/BUILD/el8_amd64_gcc12/lcg/root/6.26.11-c05101b2284100127f71c8d1f927ca38/root-6.26.11/tree/ntuple/v7/src/RField.cxx:228]

@nsmith-
Copy link
Collaborator Author

nsmith- commented Jan 16, 2024

From that printout I noticed you're using ROOT 6.26. Did you mean to start from CMSSW_14_0_0_pre0 or CMSSW_14_0_0_pre0_ROOT630? (maybe we should rename the default branch here to remind ourselves)

@Dr15Jones
Copy link

From that printout I noticed you're using ROOT 6.26.

I noticed the same thing myself from the printout. I've already moved my changes to _ROOT630 version and am rebuilding as I type.

@Dr15Jones
Copy link

So switching to ROOT 6.30 I get different problems. The DTRecSegment4D seems to now go farther and then hits a map. I get an seg fault when doing

import ROOT
model = ROOT.Experimental.RNTupleModel.Create()
model.MakeField["CSCSegment"]("test")

just doing

model.MakeField["CSCRecHit2D"]("test")

doesn't have a problem.

@Dr15Jones
Copy link

So the seg fault seems to be from an infinite recursion happening

#0  0x00007ffff303bf71 in clang::DeclContext::getPrimaryContext() () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so                                                         
#1  0x00007ffff303f7c3 in clang::DeclContext::lookup(clang::DeclarationName) const () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so                                        
#2  0x00007ffff15c8fc9 in LookupDirect(clang::Sema&, clang::LookupResult&, clang::DeclContext const*) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so                     
#3  0x00007ffff15c9a89 in CppNamespaceLookup(clang::Sema&, clang::LookupResult&, clang::ASTContext&, clang::DeclContext*, (anonymous namespace)::UnqualUsingDirectiveSet&) [clone .constprop.0] ()                                                
   from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so
#4  0x00007ffff15c219b in clang::Sema::CppLookupName(clang::LookupResult&, clang::Scope*) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so                                 
#5  0x00007ffff15c313d in clang::Sema::LookupName(clang::LookupResult&, clang::Scope*, bool) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so                              
#6  0x00007ffff06c7fe4 in cling::utils::Lookup::Tag(clang::Sema*, clang::DeclarationName const&, clang::DeclContext const*) ()                                                                                                                    
   from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so
#7  0x00007ffff06c808b in cling::utils::Lookup::Tag(clang::Sema*, char const*, clang::DeclContext const*) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so                 
#8  0x00007ffff04e04d2 in TCling::GetEnum(TClass*, char const*) const () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/cms/cmssw/CMSSW_14_0_0_pre0_ROOT630/external/el8_amd64_gcc12/lib/libCling.so                                                     
#9  0x00007ffff61df738 in TListOfEnums::FindObject(char const*) const () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libCore.so                                                                 
#10 0x00007ffff61e0575 in TListOfEnumsWithLock::FindObject(char const*) const () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libCore.so                                                         
#11 0x00007ffff61d62e4 in TEnum::GetEnum(char const*, TEnum::ESearchAction) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libCore.so                                                           
#12 0x00007fffd7342c2e in ROOT::Experimental::Detail::RFieldBase::Create(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so                                   
#13 0x00007fffd7344544 in ROOT::Experimental::Detail::RFieldBase::Create(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so
#14 0x00007fffd7345852 in ROOT::Experimental::RClassField::RClassField(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, TClass*) ()                                                  
   from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so
#15 0x00007fffd7346cd5 in ROOT::Experimental::RClassField::RClassField(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >) ()                                                           
   from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so
#16 0x00007fffd7342e11 in ROOT::Experimental::Detail::RFieldBase::Create(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so                                   
#17 0x00007fffd7344544 in ROOT::Experimental::Detail::RFieldBase::Create(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so
#18 0x00007fffd7343035 in ROOT::Experimental::Detail::RFieldBase::Create(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so                                   
#19 0x00007fffd7345d65 in ROOT::Experimental::RClassField::RClassField(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, TClass*) ()                                                  
   from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so
#20 0x00007fffd7346cd5 in ROOT::Experimental::RClassField::RClassField(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >) ()                                                           
   from /cvmfs/cms.cern.ch/el8_amd64_gcc12/lcg/root/6.30.01-1efb03e97e6d53632b90fbe779489ed9/lib/libROOTNTuple.so
[repeat from #16]

@Dr15Jones
Copy link

I think I found it, a CSCSegment internally has a member data of type std::vector<CSCSegment>.

@makortel
Copy link
Collaborator

makortel commented Jan 16, 2024

I think I found it, a CSCSegment internally has a member data of type std::vector<CSCSegment>.

Oh, we can tick off the recursion box too. This could be worth of CMSSW issue of its own (as the issue is different from OwnVector and RefToBase).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants