Skip to content
Snippets Groups Projects

WIP: Make PackTrack functional

Closed Nicole Skidmore requested to merge PackTrackHandles into master
4 unresolved threads

Making PackTrack functional so that tracks can be packed and persisted in Moore.

Note that

  • Removed checking functionality EnableCheck
  • Removed delete input functionality DeleteInput
  • Removed AlwaysCreateOutput option
Edited by Alex Pearce

Merge request reports

Pipeline #2143460 passed

Pipeline passed for 1295f6b9 on PackTrackHandles

Approval is optional

Closed by Alex PearceAlex Pearce 4 years ago (Dec 2, 2020 10:13am UTC)

Merge details

  • The changes were not merged into master.

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • Rosen Matev
  • Nicole Skidmore changed the description

    changed the description

  • added 1 commit

    Compare with previous version

  • Edited by Software for LHCb
  • and while you're at it, why not just put the content of the header file verbatim in the .cpp one?

  • Nicole Skidmore marked as a Work In Progress

    marked as a Work In Progress

  • added 1 commit

    • e17eabf3 - Making track packer functional

    Compare with previous version

  • Nicole Skidmore changed title from WIP: Give DataHandles to PackTrack to WIP: Make PackTrack functional

    changed title from WIP: Give DataHandles to PackTrack to WIP: Make PackTrack functional

  • Nicole Skidmore changed the description

    changed the description

    • Author Maintainer

      @graven Is this what you had in mind? It builds and runs just as the datahandle version did. For my knowledge is the namespace name chosen

      namespace LHCb::Converters::PackedTrack

      deliberately to match

      #include "Event/PackedTrack.h"
    • Kind of yes ;-)

      Basically, there are already several algorithms that 'convert' data from one representation to another (eg. Track V2 to Track v2, or 'Pr' tracks to Track V1 or V2, see eg. code here) And the convention kind of is to enclose them in LHCb::Converters (because they convert things), and then indicate the 'target' type, which is the most relevant for any downstream code, and then indicate some way the 'from' type...

    • and yes, this is what I just as I had in mind -- only difference are some empty lines ;-)

    • I find this confusing. We used converters for things we hopefully get rid of at some point. Why not put them into a "Packers" namespace?

    • Please register or sign in to reply
  • Nicole Skidmore unmarked as a Work In Progress

    unmarked as a Work In Progress

  • mentioned in issue Moore#204 (closed)

    • Author Maintainer

      Getting errors in Brunel

      AttributeError: Configurable 'PackTrack' does not have property 'EnableCheck'.
      Edited by Nicole Skidmore
    • That's not surprising, as those properties were removed -- so any bit of code trying to set them should be adapted. I suspect that:

      diff --git a/GaudiConf/python/GaudiConf/DstConf.py b/GaudiConf/python/GaudiConf/DstConf.py
      index 5462aa65b..7ed833c2e 100644
      --- a/GaudiConf/python/GaudiConf/DstConf.py
      +++ b/GaudiConf/python/GaudiConf/DstConf.py
      @@ -313,12 +313,7 @@ class DstConf(LHCbConfigurableUser):
       
               # Pack tracks if they were not read from the input file...
               if "Tracking" not in self.getProp("EnableUnpack"):
      -            packDST.Members += [
      -                PackTrack(
      -                    name="PackTracks",
      -                    AlwaysCreateOutput=alwaysCreate,
      -                    EnableCheck=doChecks)
      -            ]
      +            packDST.Members += [ PackTrack( name="PackTracks") ]
                   # for Run2, add packed Velo tracks
                   if ((self.getProp("DataType") in self.Run2DataTypes)
                           and (self.getProp("PVPersistence") is "RecVertex")):
      @@ -394,10 +389,9 @@ class DstConf(LHCbConfigurableUser):
                   packDST.Members += [
                       PackTrack(
                           name="PackMuonTracks",
      -                    AlwaysCreateOutput=alwaysCreate,
                           InputName="/Event/Rec/Track/Muon",
                           OutputName="/Event/pRec/Track/Muon",
      -                    EnableCheck=doChecks)
      +                )
                   ]
       
               # In MDF case, add a sub sequence for the MDF writing
      

      should do the trick...

    • If that works, does that mean that we have no tests which test the packing?

    • Indeed. But note that that property used to drive the following code:

        // Packing checks
        if ( UNLIKELY( m_enableCheck ) ) {
          // make new unpacked output data object
          LHCb::Tracks* unpacked = new LHCb::Tracks();
          put( unpacked, m_inputName + "_PackingCheck" );
      
          // unpack
          packer.unpack( *out, *unpacked );
      
          // run checks
          packer.check( *tracks, *unpacked ).ignore();
      
          // clean up after checks
          StatusCode sc = evtSvc()->unregisterObject( unpacked ).andThen( [&] { delete unpacked; } );
          if ( sc.isFailure() ) return sc;
        }
      

      (interesting how it first registers something in the TES, only to remove it afterwards...)

      So if we want a replacement for that I would propose to make a separate Gaudi::Functional::Consumer<void(const LHCb::Tracks&)> algorithm (given that these algorithms are only a handful of lines of code):

      namespace LHCb::Packers::Check {
        struct TrackPacker : Gaudi::Functional::Consumer<void(const LHCb::Tracks&)> {
          TrackPacker( const std::string& name, ISvcLocator* pSvcLocator )
            : Consumer::Consumer{name, pSvcLocator, KeyValue{"InputName", TrackLocation::Default} }{}
      
          void operator()(const LHCb::Tracks& in) const override {
           auto packer = LHCb::TrackPacker{this};
           LHCb::PackedTracks packed;
           packer.pack( in, packed );
           LHCb::Tracks unpacked;
           packer.unpack( packed, unpacked );
           packer.check( in, unpacked ).orThrow( "Packing check failed", name() );
          }
        };
        DECLARE_COMPONENT_WITH_ID( TrackPacker, "CheckTrackPacker" )
      }

      and then add that algorithm where previously EnableCheck would be enabled... that moves an 'if' from run time to configuration time, which is always a good thing IMHO.

      Now, one could perhaps wonder whether a properly written, dedicated unit test for just the packer would not be a better / sufficient solution, instead of parasitically random sampling the phase space of tracks 'on the fly' inside of some larger job, but let's keep that discussion for another occasion...

      Aside: if the pack(), and unpack() methods would return *this i.e. return a reference to their instance, instead of being void, you could write it as a daisy chain:

        LHCb::Tracks unpacked;
        LHCb::PackedTracks packed;
        LHCb::TrackPacker{this}.pack( in, packed)
                               .unpack(packed, unpacked)
                               .check( in, unpacked).orThrow("Packing check failed", name());
      Edited by Gerhard Raven
    • You may question the way in which the check was implemented, but this was to all intents and purposes a unit test of the packing and unpacking that was implemented as close to the code as could possibly be (and which was run by the author on large statistics samples whenever he made a change). We have for good reasons changed the way in which we test our code, but if you remove this, you should definitely implement an equivalent unit test.

    • Looking a bit in the configuration it turns out that we do run these checks in Brunel's xdst-to-xdst test (on 10 events, but still something). There the Brunel().Histograms="Expert" is set, which in turn means that the packing checks are enabled.

      Since all of this persistence machinery is likely to change, I would suggest to keep the checking in the simplest possible way for now. This means adding back the EnableCheck property, and copy-pasting and adapting the call to the check that was removed. You should be able to simplify it on the way and avoid putting a temporary container on the TES by changing it to something like this:

          if ( UNLIKELY( m_enableCheck ) ) {
            LHCb::Tracks unpacked;
            packer.unpack( out, unpacked );
            packer.check( tracks, unpacked ).ignore();
          }

      (does put have a side effect that the old code relied on?)

    • Please register or sign in to reply
  • Nicole Skidmore mentioned in merge request Moore!619 (merged)

    mentioned in merge request Moore!619 (merged)

  • 80 const StatusCode sc = evtSvc()->unregisterObject( tracks ).andThen( [&] {
    81 delete tracks;
    82 tracks = nullptr;
    83 } );
    84 if ( sc.isFailure() ) return sc;
    85 } else {
    86 // Clear the registry address of the unpacked container, to prevent reloading
    87 auto* pReg = tracks->registry();
    88 if ( pReg ) pReg->setAddress( nullptr );
    15 #include "GaudiAlg/Transformer.h"
    16
    17 /** @class PackTrack PackTrack.h
    18 *
    19 * Pack track container
    20 *
    21 * @author Olivier Callot
  • Andre Gunther marked as a Work In Progress

    marked as a Work In Progress

  • assigned to @nskidmor

  • added 1 commit

    Compare with previous version

  • closed

  • Alex Pearce changed the description

    changed the description

  • Sevda Esen mentioned in merge request !3081 (closed)

    mentioned in merge request !3081 (closed)

  • Please register or sign in to reply
    Loading