Collection of scripts and small programs used by the EVN Support Scientists at JIVE during the regular data processing of EVN observations.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

192 рядки
7.2 KiB

  1. #!/usr/bin/env python3
  2. """
  3. Given a VEX file, it creates a new VEX file that is a subset of the given one,
  4. dropping all the information (stations, source, PI names) that are not included
  5. in the provided inputs.
  6. Usage: split_vexfile.py [-o outputfile] <vexfile> <experiment> <PI name> <first scan> <last scan>
  7. Options:
  8. vexfile : str name of the original vex file (note that this file is not modified).
  9. experiment : str name of the experiment for the final (output) vex file.
  10. the original experiment name and all the other ones stored
  11. in the vex file will be removed.
  12. pi name :str name of the pi for this experiment. all the other names will
  13. be removed.
  14. first scan : int number of the first scan to be included in the new vex file.
  15. all scans previous to this one will be removed from the vex file.
  16. last scan : int number of the last scan to be included in the new vex file.
  17. all scans after this one will be removed from the vex file.
  18. optional parameters:
  19. -o outputfile : str the filename for the output vex file. if not provided, the filename will
  20. be <experiment>.vex
  21. Version: 1.0
  22. Date: May 2018
  23. Written by Benito Marcote (marcote@jive.eu)
  24. """
  25. import sys
  26. import argparse
  27. from vex import vex
  28. usage = "%(prog)s [-h] [-v] [-o outputfile] <vexfile> <experiment> <PI name> <scans>"
  29. description="""Given a VEX file, it creates a new VEX file that is a subset of the given one,
  30. dropping all the information (stations, source, PI names) that are not included in the provided inputs.
  31. In e-EVN observations, where one VEX file contains different experiments, this script produces
  32. a new VEX file containing the information for only one of the experiments. And thus the MS generated
  33. by j2ms2 will not contain sensitive information from the other experiments.
  34. """
  35. help_vexfile = 'Name of the original vex file to read (note that this file is not modified).'
  36. help_experiment = """Name of the experiment for the final (output) vex file.
  37. The original experiment name and all the other ones stored
  38. in the vex file will be removed."""
  39. help_piname = "Name of the PI for this experiment. all the other names will be removed."
  40. help_firstscan ="""Number of the first scan to be included in the new vex file.
  41. All scans previous to this one will be removed from the vex file."""
  42. help_lastscan = """Number of the last scan to be included in the new vex file.
  43. All scans after this one will be removed from the vex file."""
  44. help_scans = """Scans to be included in the vex file. You can specify ranges or individual scans.
  45. Ranges can be specify as: XXX~YYY to include scans XXX to YYY, both included.
  46. Different individual scans or ranges can be provided as comma-separated lists
  47. (with no spaces in between). e.g. 100~110,150,120~130 to include scans
  48. 100 to 110, 150, and 120 to 130."""
  49. help_verbose = "Run in verbose mode. Prints all data to be discarded."
  50. help_outputfile = "Filename for the output vex file. if not provided, the filename will be <experiment>.vex"
  51. parser = argparse.ArgumentParser(description=description, prog='split_vexfile.py', usage=usage)
  52. parser.add_argument('vexfile', type=str, help=help_vexfile)
  53. parser.add_argument('experiment', type=str, help=help_experiment)
  54. parser.add_argument('piname', type=str, help=help_piname)
  55. # parser.add_argument('firstscan', type=int, help=help_firstscan)
  56. # parser.add_argument('lastscan', type=int, help=help_lastscan)
  57. parser.add_argument('scans', type=str, help=help_scans)
  58. parser.add_argument('--version', action='version', version='%(prog)s 1.0')
  59. parser.add_argument("-v", "--verbose", default=False, action="store_true" , help=help_verbose)
  60. parser.add_argument("-o", "--outputfile", type=str, default=None, help=help_outputfile)
  61. args = parser.parse_args()
  62. verbose = args.verbose
  63. if args.outputfile is None:
  64. outputfile = args.experiment.lower() + '.vex'
  65. else:
  66. outputfile = args.outputfile
  67. # assert args.firstscan <= args.lastscan
  68. # Process the scans to be imported
  69. scans_to_include = set()
  70. scan_list = args.scans.split(',')
  71. for a_scan_list in scan_list:
  72. if '~' in a_scan_list:
  73. # it is a range
  74. assert a_scan_list.count('~') == 1
  75. s1,s2 = [int(i) for i in a_scan_list.split('~')]
  76. assert s1 <= s2
  77. for i in range(s1, s2+1):
  78. scans_to_include.add(i)
  79. else:
  80. # it is an isolated scan
  81. scans_to_include.add(int(a_scan_list))
  82. vexfile = vex.Vex(args.experiment, vexfile=args.vexfile)
  83. if verbose:
  84. print(f'{args.vexfile} has been read')
  85. # Updating experiment name
  86. vexfile['GLOBAL']['EXPER'].value = args.experiment.upper()
  87. if verbose:
  88. print(f'$GLOBAL>$EXPER updated to {args.experiment.upper()}')
  89. oldexpname = [i for i in vexfile['EXPER'].keys() if 'comment' not in i]
  90. if len(oldexpname) != 1:
  91. raise ValueError('Many definitions found under $EXPER. Only one expected.')
  92. oldexpname = oldexpname[0]
  93. vexfile['EXPER'][oldexpname].name = args.experiment.upper()
  94. if verbose:
  95. print(f'$EXPER>def {oldexpname} updated to {args.experiment.upper()}')
  96. vexfile['EXPER'][oldexpname]['exper_name'].value = args.experiment.upper()
  97. if verbose:
  98. print(f'$EXPER>exper_name updated to {args.experiment.upper()}')
  99. descr = vexfile['EXPER'][oldexpname]['exper_description'].value
  100. if len(descr) > 1:
  101. if '"e-EVN' in descr[0]:
  102. descr[1] = f' {args.experiment.upper()}"'
  103. vexfile['EXPER'][oldexpname]['exper_description'].value = descr
  104. if verbose:
  105. print(f'$EXPER>exper_description updated to contain only {args.experiment.upper()}')
  106. vexfile['EXPER'][oldexpname]['PI_name'].value = f'"{args.piname}"'
  107. if verbose:
  108. print(f'EXPER>PI_name updated to {args.piname}')
  109. # Keep sources that should be included
  110. # Keep only specified scans
  111. allsources = set([i for i in vexfile['SOURCE'].keys() if 'comment' not in i])
  112. sources = set()
  113. allscans = [i for i in vexfile['SCHED'].keys() if 'comment' not in i]
  114. if len(scans_to_include) == 0:
  115. print('WARNING: no scans to be included')
  116. for a_scan in allscans:
  117. scannumber = int(a_scan[2:])
  118. # if (scannumber < args.firstscan) or (scannumber > args.lastscan):
  119. if scannumber not in scans_to_include:
  120. del vexfile['SCHED'][a_scan]
  121. if verbose:
  122. print(f'Scan {a_scan} has been removed')
  123. else:
  124. # Double checking (in case the key exists, otherwise is within the 'start' key
  125. if 'source' in vexfile['SCHED'][a_scan]:
  126. sources.add(vexfile['SCHED'][a_scan]['source'].value)
  127. else:
  128. temp = vexfile['SCHED'][a_scan]['start'].value
  129. # print(temp)
  130. # print(temp.strip())
  131. # print(temp.strip().split(';'))
  132. temp = [vex.Entry.entry_from_text(i) for i in temp.strip().split(';')[1:]]
  133. sources.add([i.value for i in temp if i.key == 'source'][0])
  134. # Remove the sources from other experiments
  135. for a_source in allsources.difference(sources):
  136. del vexfile['SOURCE'][a_source]
  137. if verbose:
  138. print(f'Source {a_source} has been removed')
  139. # Write the VEX info to a file
  140. vexfile.to_file(outputfile)
  141. if verbose:
  142. print(f'File {outputfile} has been written')