Collection of scripts and small programs used by the EVN Support Scientists at JIVE during the regular data processing of EVN observations.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

183 lines
7.3 KiB

  1. #!/usr/bin/env python3
  2. import os
  3. import sys
  4. import tempfile
  5. import argparse
  6. import subprocess
  7. import datetime
  8. __version__ = 1.1
  9. __prog__ = 'nme_standardplots.py'
  10. usage = "%(prog)s [-h] <experiment_name> <scan_number>\n"
  11. description = """Produces auto- and cross- correlations from a .cor file produced during a NME.
  12. This program retrieves the .cor file expected to be located in jops@tail.sfxc that has been produced manually from a support scientist during a NME. Then it creates the associated MS file and runs jplotter to produce the plots.
  13. The program assumes that the experiment is being conducted today (at the time of the call to this script).
  14. Otherwise, you may need to specify the date with the '-d' or '--date' option.
  15. """
  16. def scp(originpath, destpath):
  17. """Does a scp from originpath to destpath. If the process returns an error,
  18. then it raises ValueError.
  19. """
  20. process = subprocess.call(["scp", originpath, destpath], shell=False,
  21. stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
  22. if process != 0:
  23. raise ValueError(f"\nError code {process} when running scp {originpath} {destpath}.")
  24. def get_vixfile(expname: str):
  25. """Copies the .vix file from ccs to the current directory for the given expname.
  26. """
  27. if not os.path.isfile(f"{expname.lower()}.vax"):
  28. scp(f"jops@ccs:/ccs/expr/{expname.upper()}/{expname.lower()}.vax", '.')
  29. print('Vix file copied to the current directory.')
  30. if not os.path.isfile(f"{expname.upper()}.vix"):
  31. os.symlink(f"{expname.lower()}.vax", f"{expname.upper()}.vix")
  32. print('Symbolic link created to vix file.')
  33. # Because j2ms2 will search for a vix file named as the current directory
  34. pwd = os.getcwd().split('/')[-1]
  35. if not os.path.isfile(f"{pwd}.vix"):
  36. os.symlink(f"{expname.lower()}.vax", f"{pwd}.vix")
  37. def copy_cor_file(expname: str, scanno: str, date: str):
  38. """Copies the correlation file produced by a local correlation during an NME for the experiment
  39. name 'expname' and for the scan number 'scanno' to the current directory.
  40. - Inputs
  41. expname : experiment name (case-insensitive)
  42. scanno : str with the scan number to be processed as expected from the syntax 'scan{scanno}.cor'.
  43. date : date for the given experiment in the form YYYY_month, where month is the full name of the month.
  44. """
  45. scp(f"jops@tail.sfxc:/home/jops/sfxc/ftp/{date}/{expname.lower()}/output/scan{scanno}.cor", ".")
  46. print(f"Correlation file 'scan{scanno}.cor' copied from tail.sfxc.")
  47. def j2ms2(expname: str, scanno: str):
  48. """Runs j2ms2 in the retrieved correlation file called 'scan{scanno}.cor' and produces the
  49. '{expname}-scan{scanno}.ms' file. If this MS file already exists, it will be removed.
  50. expname is case insensitive.
  51. """
  52. msfile = f"{expname.lower()}-scan{scanno}.ms"
  53. if os.path.exists(msfile):
  54. print("Removing existing MS file.")
  55. process = subprocess.call(["rm", "-rf", msfile], shell=True, stdout=subprocess.PIPE,
  56. stderr=subprocess.STDOUT, bufsize=1)
  57. print("Running j2ms2...")
  58. process = subprocess.Popen(f"j2ms2 -o {msfile} scan{scanno}.cor", shell=True,
  59. stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  60. while process.poll() is None:
  61. out = process.stdout.readline().decode('utf-8')
  62. sys.stdout.write(out)
  63. sys.stdout.flush()
  64. print(f"MS file '{msfile}' created.")
  65. def standardplots(expname: str, scanno: str, refant: str):
  66. """Runs standardplots to create auto- and cross- correlations during an NME for the specified
  67. experiment (expname; case insensitive) and scan number, expecting a MS in the current directory called
  68. {expname.lower()}-scan{scanno}.ms
  69. """
  70. def open_ms(expname, scanno):
  71. tmp = tempfile.NamedTemporaryFile()
  72. return f"ms {expname.lower()}-scan{scanno}.ms;refile {tmp.name};indexr"
  73. def auto_plots(expname, scanno):
  74. todo = ["bl auto"]
  75. todo += ["fq */p"]
  76. todo += ["pt ampchan"]
  77. todo += ["ch none"]
  78. todo += ["avc none"]
  79. todo += ["avt vector"]
  80. todo += ["ckey p[RR]=2 p[LL]=3 p[RL]=4 p[LR]=5 p[none]=1"]
  81. todo += ["sort bl sb"]
  82. todo += ["new sb false"]
  83. todo += ["multi true"]
  84. todo += ["nxy 1 4"]
  85. todo += ["y 0 1.8"]
  86. todo += [f"refile {expname.lower()}-scan{scanno}-auto.ps/cps"]
  87. todo += ["pl"]
  88. return ';'.join(todo)
  89. def cross_plots(expname, scanno, refant):
  90. todo = [f"bl {refant}* -auto"]
  91. todo += ["fq *"]
  92. todo += ["pt ampchan"]
  93. todo += ["ch none"]
  94. todo += ["avc none"]
  95. todo += ["avt vector"]
  96. todo += ["ckey p[RR]=2 p[LL]=3 p[RL]=4 p[LR]=5 p[none]=1"]
  97. todo += ["sort bl sb"]
  98. todo += ["new sb false"]
  99. todo += ["multi true"]
  100. todo += ["nxy 1 4"]
  101. todo += ["y local"]
  102. todo += [f"refile {expname.lower()}-scan{scanno}-cross.ps/cps"]
  103. todo += ["pl"]
  104. return ';'.join(todo)
  105. for afile in (f"{expname.lower()}-scan{scanno}-auto.ps", f"{expname.lower()}-scan{scanno}-cross.ps"):
  106. if os.path.isfile(afile):
  107. print("Removing existing plot files...")
  108. # process = subprocess.Popen(["rm", "-f", f"{afile}"], shell=True, stdout=subprocess.PIPE,
  109. process = subprocess.Popen(f"rm -f {afile}", shell=True, stdout=subprocess.PIPE,
  110. stderr=subprocess.STDOUT, bufsize=1)
  111. todo = [open_ms(expname, scanno), auto_plots(expname, scanno), cross_plots(expname, scanno, refant)]
  112. print("Running jplotter...")
  113. print(f"\n\njplotter -c {';'.join(todo)}\n\n")
  114. process = subprocess.Popen(f"jplotter -c '{';'.join(todo)}'", shell=True, stdout=subprocess.PIPE,
  115. stderr=subprocess.STDOUT, bufsize=1)
  116. while process.poll() is None:
  117. out = process.stdout.readline().decode('utf-8')
  118. sys.stdout.write(out)
  119. sys.stdout.flush()
  120. print("Plots produced and saved.")
  121. if __name__ == '__main__':
  122. # Input parameters
  123. parser = argparse.ArgumentParser(description=description, prog=__prog__, usage=usage,
  124. formatter_class=argparse.RawTextHelpFormatter)
  125. parser.add_argument('expname', type=str, help='Name of the EVN experiment (case insensitive).')
  126. parser.add_argument('scan_number', type=str,
  127. help='Correlated scan number (as given in the <scan{scan_number}.cor> file name).')
  128. parser.add_argument('-d', '--date', type=str, default=None,
  129. help='Date of the NME, given as YYYY_month, with month the full name of the month.')
  130. parser.add_argument('-r', '--refant', type=str, default='Ef',
  131. help='Reference antenna to make plots. By default it is Ef.')
  132. parser.add_argument('-v', '--version', action='version',
  133. version='%(prog)s {}'.format(__version__))
  134. args = parser.parse_args()
  135. if args.date is None:
  136. nme_date = datetime.datetime.today().strftime('%Y_%B').lower()
  137. else:
  138. nme_date = args.date
  139. get_vixfile(args.expname)
  140. copy_cor_file(args.expname, args.scan_number, nme_date)
  141. j2ms2(args.expname, args.scan_number)
  142. standardplots(args.expname, args.scan_number, args.refant)