Improve separation between fetching raw events and processed events; could be useful to disentangle those two locks in the future.
Reorganize use of FinishEvent so that there is a queue of finish-able events; we attempt to order the events before finishing them, to make reading more efficient.
Currently this is implemented by starting a thread with the sole purpose of finishing events.
The thread will work continuously to read events and finish them; it balances itself because the more it falls behind, the better-ordered events will become.  (We establish a hard-coded maximum queue size of 1000ish, to prevent ourselves from exhausting memory.)
Profiling results from this change are still pending; we expect it will help, but even if it doesn't we have much more control over the file access this way (including the option of implementing asynchronous reads).
Based on a suggestion from Mike, implement a cleaner way of specifying the branches of the raw tree to read.
Update the EdisonBatch script to be similar to the HopperBatch script, in particular to be compatible with using xrootd.
Fix a silly bug with an untested commit -- I can't unprecondition fX for an un-denoisable event.
Fix a data corruption issue -- not fully understood, but somehow using the raw and processed trees synchronously was causing data corruption issues.  (Possibly to do with TRefs?)
Parallel calls to TGraph::Eval seem to cause problems (even without a spline).  Strange, but avoided with this commit.
Although we were permitting the io thread to maintain events in a sorted queue, compute threads weren't having much luck acquiring the lock needed to insert events into it.  The result was that events would be added to the queue in batches, so ordering was far from optimal.
Now, we reduce the priority of the io thread to ensure compute threads get priority when they try to insert an event.
Additionally, increase the length of sleeps from 100ms to 5sec, since 100ms is ridiculously short.
Finally, force the io thread to pause for a minute at the beginning, to give the computation threads a chance of building up the start of a queue.
Add useful watches for understanding the impact of the new io thread.
Allow the io thread to accumulate as many as 5000 events in its queue.  Not all of those events will have vectors associated with them.  We'll see if that uses too much memory...
Since we're now running the io thread with low priority, maybe it makes sense to run a compute thread on every CPU again.  Incrementing the number of compute threads requested by one.
Too many times code has crashed without a useful backtrace.  Making compilation "debugged" by default.
Consolidate the mutexes which covered root-related interactions.  I had thought I could get away with decoupling the raw and processed files, but so far that hasn't been the case.
Add a watch for the time required by the main thread to acquire a RootInterface lock.  This turns out to be dominant, indicating the FinishEvent thread is starving the compute threads.
Force FinishEventsThread to wait for a sufficient number of events to accumulate on the queue before continuing.  This is superior to the previous option of waiting a fixed amount of time before beginning work.
Retract an earlier comment -- it does seem acceptable to use raw and processed trees simultaneously.  This is very good, because letting the raw tree block AcceptEvent was starving it.
In case an event actually won't be denoised, skip straight to outputting it rather than putting it on the queue.  This saves lots of locking and unlocking operations, and allows us to combine two actions which would be forced to run in serial anyway.