refactored to put more preprocessing up front, outside of loop