Avoid holding excessive numbers of file handles open

When running threaded jobs with 10 threads, the job would fail because
it ran out of file handles. This change allows the code to only open
one instance of the TFile and then closes the file once all necessary
information has been read. This works since the objects pulled from
the TFile are cloned so memory ownership is transfered.

As part of the change, memory management was simplified via the use
of std::unique_ptr.