          return thread
  
      def end_thread(self, thread):
          """ On termination output message and join thread back to main """
          print("Exit requested! The trainer will complete its current cycle, "
                "save the models and quit (it can take up a couple of seconds "
                "depending on your training speed). If you want to kill it now, "
                "press Ctrl + c")
          self.stop = True
          thread.join()
          sys.stdout.flush()
  
      def process_thread(self):
 
</s> remove             print("Loading data, this may take a while...")
 </s> add             logger.info("Loading data, this may take a while...") </s> remove         for _ in range(self.thread_count):
            thread = threading.Thread(target=target, args=args, kwargs=kwargs)
            thread.daemon = True
 </s> add         logger.debug("Starting thread(s): '%s'", self._name)
        for idx in range(self._thread_count):
            name = "{}_{}".format(self._name, idx)
            logger.debug("Starting thread %s of %s: '%s'",
                         idx + 1, self._thread_count, name)
            thread = FSThread(name=name,
                              target=self._target,
                              args=self._args,
                              kwargs=self._kwargs)
            thread.daemon = self.daemon </s> remove         print("\n[SPATIO-TEMPORAL FILTERING]")  # Tidy up cli output
        print("NB: The process only processes the alignments for the first "
              "face it finds for any given frame\n"
              "    For best results only run this when:\n"
              "      - there is only a single face in the alignments file\n"
              "      - all false positives have been removed\n")
 </s> add         logger.info("[SPATIO-TEMPORAL FILTERING]")  # Tidy up cli output
        logger.info("NB: The process only processes the alignments for the first "
                    "face it finds for any given frame. For best results only run this when "
                    "there is only a single face in the alignments file and all false positives "
                    "have been removed") </s> remove     def join_threads(self):
        """ Join the running threads """
        for thread in self.threads:
 </s> add     def join(self):
        """ Join the running threads, catching and re-raising any errors """
        logger.debug("Joining Threads: '%s'", self._name)
        for thread in self._threads:
            logger.debug("Joining Thread: '%s'", thread._name)  # pylint: disable=protected-access </s> remove         print("Using live preview.\n"
              "Press 'ENTER' on the preview window to save and quit.\n"
              "Press 'S' on the preview window to save model weights "
              "immediately")
 </s> add         logger.info("Using live preview.\n"
                    "Press 'ENTER' on the preview window to save and quit.\n"
                    "Press 'S' on the preview window to save model weights "
                    "immediately")
        logger.info("Exit requested! The trainer will complete its current cycle, "
                    "save the models and quit (it can take up a couple of seconds "
                    "depending on your training speed). If you want to kill it now, "
                    "press Ctrl + c")
          return thread
  
      def end_thread(self, thread):
          """ On termination output message and join thread back to main """
        logger.info("Exit requested! The trainer will complete its current cycle, "
                    "save the models and quit (it can take up a couple of seconds "
                    "depending on your training speed). If you want to kill it now, "
                    "press Ctrl + c")
        logger.info("Exit requested! The trainer will complete its current cycle, "
                    "save the models and quit (it can take up a couple of seconds "
                    "depending on your training speed). If you want to kill it now, "
                    "press Ctrl + c")
        logger.info("Exit requested! The trainer will complete its current cycle, "
                    "save the models and quit (it can take up a couple of seconds "
                    "depending on your training speed). If you want to kill it now, "
                    "press Ctrl + c")
        logger.info("Exit requested! The trainer will complete its current cycle, "
                    "save the models and quit (it can take up a couple of seconds "
                    "depending on your training speed). If you want to kill it now, "
                    "press Ctrl + c")
          self.stop = True
          thread.join()
          sys.stdout.flush()
  
      def process_thread(self):
keep keep keep keep replace replace replace replace keep keep keep keep keep
 Logging (#541)

* Convert prints to logger. Further logging improvements. Tidy  up

* Fix system verbosity. Allow SystemExit

* Fix reload extract bug

* Child Traceback handling

* Safer shutdown procedure

* Add shutdown event to queue manager

* landmarks_as_xy > property. GUI notes + linting. Aligner bugfix

* fix FaceFilter. Enable nFilter when no Filter is supplied

* Fix blurry face filter

* Continue on IO error. Better error handling

* Explicitly print stack trace tocrash log

* Windows Multiprocessing bugfix

* Add git info and conda version to crash log

* Windows/Anaconda mp bugfix

* Logging fixes for training 
scripts/train.py