#!/usr/bin/env python3

#
# geiger.py - Acquire and display data from MightyOhm Geiger counter
#
# Copyright (c) 2020 by Everett A. Lipman.  All rights reserved.
#
# 04Jul20  Added log file and completion time printout
# 30Jun20  Added serial devices for other operating systems
# 18Jun20  Adjusted digits in display
# 17Jun20  Everett Lipman
#
USAGE="""
usage: geiger.py [time]

       time is the duration of the measurement in seconds

       If time is not specified, counter will run for one year or until killed.
"""
N_ARGUMENTS = (0,1)

SERDEV = '/dev/ttyUSB0'  # Linux
# SERDEV = '/dev/cu.usbserial-FT3VKTR7'  # Mac
# SERDEV = 'COM1'  # Windows

SERSPEED = 9600
SERTIMEOUT = 3
INLEN = 35  # length of stripped data string from MightyOhm counter

LOGFILE="geigerlog.txt"

import sys
import os
import time
import serial
###############################################################################

def usage(message = ''):
   sys.stdout = sys.stderr
   if message != '':
      print(message)
   print(USAGE)

   sys.exit(1)
###############################################################################

def check_arguments():
   """Check command line arguments for proper usage.

      returns: number of arguments
   """
   nargs = len(sys.argv) - 1
   progname = os.path.basename(sys.argv[0])
   flag = True
   if nargs != 0 and N_ARGUMENTS[-1] == '*':
      flag = False
   else:
      for i in N_ARGUMENTS:
         if nargs == i:
            flag = False
   if flag:
      usage()

   return(nargs)
###############################################################################

if __name__ == '__main__':
   nargs = check_arguments()

   if nargs != 0:
      try:
         counttime = float(sys.argv[1])
      except ValueError:
         usage()
   else:
      counttime = 31556925.9747

   ser = serial.Serial(SERDEV, SERSPEED, timeout=SERTIMEOUT)

   print()
   print('Counting for %.0f seconds...' % counttime)
   print()

   count = 0
   t0 = time.perf_counter()
   elapsed = 0
   while elapsed <= counttime:
      indata = ser.readline()
      elapsed = time.perf_counter() - t0

      intext = indata.decode().strip()
      inlist = intext.split(', ')
      if len(intext) != INLEN:
         continue
      if inlist[-1] != 'SLOW':
         print("\nWARNING: mode is not 'SLOW'\n", file=sys.stderr)
      
      count = count + int(inlist[1])
      minutes = elapsed/60.0
      rate = count/minutes
      rerr = count**0.5/minutes

      print('count: %d  elapsed: %.1f s  rate: %.2f +/- %.2f cpm'
             % (count, elapsed, rate, rerr))

   endtime = time.ctime()
   minutes = elapsed/60.0
   rate = count/minutes
   err = count**0.5
   rerr = err/minutes

   print()
   print('Measurement completed: %s' % endtime)
   print()
   print('Elapsed time: %.1f s' % elapsed)
   print()
   print(' Total count: %d +/- %.1f' % (count, err))
   print()
   print('  Count rate: %.3f +/- %.2f cpm' % (rate, rerr))
   print()

   try:
      outfile = open(LOGFILE, 'a')
   except:
      print('Warning: could not open log file "%s"\n'
             % LOGFILE, file=sys.stderr)
      exit(1)

   print('\nMeasurement completed: %s' % endtime, file=outfile)
   print('\nElapsed time: %.1f s' % elapsed, file=outfile)
   print('\n Total count: %d +/- %.1f' % (count, err), file=outfile)
   print('\n  Count rate: %.3f +/- %.2f cpm' % (rate, rerr), file=outfile)
   print('=================================================================\n',
         file=outfile)

   outfile.close()
