diff server.py @ 1:7e3085fc60c1 draft default tip

master branch Updating
author lain
date Wed, 30 Aug 2023 14:21:18 +0000
parents b58b229c4cbf
children
line wrap: on
line diff
--- a/server.py	Fri Mar 03 14:10:24 2023 +0000
+++ b/server.py	Wed Aug 30 14:21:18 2023 +0000
@@ -40,21 +40,22 @@
   "theo_mass": "",
   "delta_ppm": "ppm",
   "rdbequiv": "",
-  "composition": "",
-  "attribution": "fragment",
+  "composition": "fragment",
+  "attribution": "composition",
 }
 
 MS_2_SNOOP_HEADER = {
   "name": str,
   "inchikey": str,
-  "composition": str,
+  # "composition": str,
+  "composition": lambda *args:"",
   "fragment": str,
   "fragment_mz": str,
   "ppm": str,
   "fileid": str,
   "correlation": str,
-  "abs_intensity": lambda x:float(x) * 100,
-  "rel_intensity": lambda x:float(x) * 100,
+  "abs_intensity": lambda x:float(x), # * 100,
+  "rel_intensity": lambda x:float(x) * 100 if x != "" else "",
   "valid_corelation": str
 }
 
@@ -233,7 +234,7 @@
       method: "default is {{ defaults.method }}"
     meta:
       author: Lain Pavot
-      version: 1.1.0
+      version: 1.2.0
     shortcuts:
       help: h
       ## will autogenerate -i for input and -m for method
@@ -422,13 +423,11 @@
   config.placeholders[ADD_SPECTRUM_FORM] = ""
   config.placeholders[EMBED_JS_PLACEHOLDER] = ""
   config.placeholders[TAB_LIST_PLACEHOLDER] = ""
-  config.placeholders["DEFAULT_MIN_MZ"] = "50"
-  config.placeholders["DEFAULT_MAX_MZ"] = "500"
+  # config.placeholders["DEFAULT_MIN_MZ"] = "50"
+  # config.placeholders["DEFAULT_MAX_MZ"] = "500"
   config.placeholders["DEFAULT_RESOLUTION_LOW"] = ""
   config.placeholders["DEFAULT_RESOLUTION_HIGH"] = "selected=\"selected\""
   config.placeholders["DEFAULT_RESOLUTION_UNSET"] = ""
-  config.placeholders["DEFAULT_MIN_RT"] = "0.9"
-  config.placeholders["DEFAULT_MAX_RT"] = "1.4"
   return config
 
 def parse_parameters(config):
@@ -458,6 +457,9 @@
       + '\n'.join(parameters.errors)
     )
 
+  parameters.placeholders["DEFAULT_MIN_RT"] = str(arguments.rt_min)
+  parameters.placeholders["DEFAULT_MAX_RT"] = str(arguments.rt_max)
+
   if arguments.sample_type == COMPOUND_MIX:
     parameters["form_template"] = os.path.join(
       parameters["root_dir"],
@@ -467,7 +469,7 @@
       parameters["root_dir"],
       parameters.templates.main_mix
     )
-  elif arguments.sample_type == COMPOUND_REF:
+  else: # elif arguments.sample_type == COMPOUND_REF:
     parameters["form_template"] = os.path.join(
       parameters["root_dir"],
       parameters.templates.form_ref
@@ -566,6 +568,7 @@
       arguments["method"] = "cf_pfem_urine_qtof"
     else:
       arguments["method"] = "cf_pfem_urine_method1_qtof-msms"
+      arguments["method"] = "toulouse-metatoul-agromix__ft-esi__msms"
   if arguments["sample_type"] == COMPOUND_MIX:
     check_mix_compound_files(parameters)
   more_info_in_logs(parameters)
@@ -579,11 +582,14 @@
       for metadata in arguments.raw_metadata
     ]
   except ValueError:
-    parameters.logger.error(
-      "Metadata/file names does not start with `[0-9]+-[0-9]+_.*` . "
-      "This is necessary in the case of compounds mix."
-    )
-    sys.exit(-1)
+    ## file does not start with `[0-9]+-[0-9]+_.*`: probably
+    ## a ms2snoop file.
+    return
+    # parameters.logger.error(
+    #   "Metadata/file names does not start with `[0-9]+-[0-9]+_.*` . "
+    #   "This is necessary in the case of compounds mix."
+    # )
+    # sys.exit(-1)
   runs, samples = zip(*numbarz)
   if not all(runs[0] == i for i in runs[1:]):
     parameters.logger.error(
@@ -806,8 +812,8 @@
           ms_data["abs_intensity"],
           ms_data["rel_intensity"],
           ms_data["ppm"],
+          ms_data["fragment"],
           ms_data["composition"],
-          ms_data["fragment"],
           str(ms_data["valid_corelation"] == "TRUE").lower(),
           "true" if ms_data.get("correlation") == "1" else "false"
         )
@@ -827,11 +833,10 @@
   adds the compound to the tab list,
   creates the js file for this tab
   """
-  if len([x for x in ms_peak_table if x.split(", ")[7] == "\"true\""]) > 1:
-    for i in range(len(ms_peak_table)):
-      ms_peak_table[i] = ", ".join(
-        ms_peak_table[i].split(", ")[:-1] + [", \"false\""]
-      )
+  ignore_multiple_parent_ion(ms_peak_table)
+  determine_min_max_mz(ms_peak_table)
+  guess_relative_intensities(ms_peak_table)
+  accept_all_fragments_if_all_false(ms_peak_table)
   config.placeholders[MS_PEAK_VALUES_PLACEHOLDER] = f"""[
     {','.join('['+line+']' for line in ms_peak_table)}
   ]"""
@@ -853,6 +858,64 @@
   if index == 1:
     config.placeholders[ACTIVE_TAB_PLACEHOLDER] = ""
 
+def determine_min_max_mz(ms_peak_table):
+  mz_list = [
+    float(ms_peak_table[i].split(", ")[0].strip("\""))
+    for i in range(len(ms_peak_table))
+  ]
+  config.placeholders["DEFAULT_MIN_MZ"] = str(min(mz_list))
+  config.placeholders["DEFAULT_MAX_MZ"] = str(max(mz_list))
+
+def guess_relative_intensities(ms_peak_table):
+  if all(
+    ms_peak_table[i].split(", ")[2].strip("\"") == ""
+    for i in range(len(ms_peak_table))
+  ):
+    absolute_intensities = [
+      float(ms_peak_table[i].split(", ")[1].strip("\""))
+      for i in range(len(ms_peak_table))
+    ]
+    greatest = float(max(absolute_intensities))
+    relative_intensities = [
+      intensity / greatest * 100
+      for intensity in absolute_intensities
+    ]
+    replace_ms_table_value(ms_peak_table, 2, relative_intensities)
+
+def ignore_multiple_parent_ion(ms_peak_table):
+  if len([
+    None for x in ms_peak_table
+    if x.split(", ")[7].strip("\"") == "true"
+  ]) > 1:
+    ## if more than one is the precursor, then none is the precursor
+    replace_ms_table_value(ms_peak_table, 7, "\"false\"")
+
+def accept_all_fragments_if_all_false(ms_peak_table):
+  if all(
+    ms_peak_table[i].split(", ")[6].strip("\"") == "false"
+    for i in range(len(ms_peak_table))
+  ):
+    replace_ms_table_value(ms_peak_table, 6, "true")
+
+def replace_ms_table_value(ms_peak_table, index, value, sep=", "):
+  length = len(ms_peak_table)
+  if not isinstance(value, list):
+    if isinstance(value, str):
+      value = [value.join('""')] * length
+    else:
+      value = [str(value)] * length
+  if not isinstance(value[0], str):
+    value = [str(x) for x in value]
+  count = ms_peak_table[0].count(sep)
+  endindex = count - index
+  neg_endindex = -endindex
+  for i in range(length):
+    ms_peak_table[i] = sep.join((
+      *ms_peak_table[i].split(sep, index)[:index],
+      value[i],
+      *ms_peak_table[i].rsplit(sep, endindex)[neg_endindex:]
+    ))
+
 def fragnot_extractor(config, *line):
   """
   Fragnot processor - extracts one fragnot line of content and
@@ -862,7 +925,7 @@
     FRAGNOT_HEADER[header]: line[i].strip()
     for i, header in enumerate(FRAGNOT_HEADER)
   }
-  fragnot_data["composition"] = "unknown"
+  # fragnot_data["composition"] = "unknown"
   fragnot_data["valid_corelation"] = config.arguments.validation
   return fragnot_data
 
@@ -923,7 +986,7 @@
   else:
     gen_dir = tempfile.gettempdir()
     config.workdir.tmp_dir = gen_dir
-  shutil.copy(os.path.join(config["root_dir"], "common.js"), gen_dir)
+  shutil.copy(os.path.join(config["root_dir"], "src", "common.js"), gen_dir)
   config.logger.info(f"Outputs will be generated in {config.workdir.tmp_dir}")
   return gen_dir
 
@@ -941,11 +1004,13 @@
     def do_POST(self):
       content_length = int(self.headers.get("Content-Length"))
       json_bytes = self.rfile.read(content_length).decode("utf-8")
-      json_list = json.loads(json_bytes)
-      for i, obj in enumerate(json_list):
-        print(obj)
-        if obj:
-          config["json_result"][i] = obj
+      # json_list = json.loads(json_bytes)
+      # for i, obj in enumerate(json_list):
+      #   print(obj)
+      #   if obj:
+      #     config["json_result"][i] = obj
+      json_obj = json.loads(json_bytes)
+      config["json_result"][json_obj["index"]] = json_obj["object"]
       save_json(config)
       self.send_head()
       self.wfile.write(json_bytes.encode("utf-8"))
@@ -974,7 +1039,7 @@
   """
   prepare and runs the server, with the handler for the given directory
   """
-  ip, port = config.network.ip, config.network.port
+  ip, port = config.arguments.ip, int(config.arguments.port)
   config.logger.debug(f"IP and port: {ip}:{port}")
   socketserver.TCPServer.allow_reuse_address = True
   config.logger.debug(f"Allow reuse adress.")
@@ -1066,6 +1131,10 @@
   logger.info("...")
 
 if __name__ == "__main__":
+  print(os.listdir("test-data"))
+
+  if not os.path.exists("config.yml"):
+    shutil.copy("config.default.yml", "config.yml")
 
   base_config = parse_config()
   config = parse_parameters(base_config)
@@ -1075,6 +1144,12 @@
   """
   arguments = config.arguments
 
+  if arguments.pid:
+    print(arguments.pid)
+    with open(arguments.pid, "w") as pid_file:
+      pid_file.write(str(os.getpid()))
+    atexit.register(lambda:os.unlink(arguments.pid))
+
   config.logger.info(f"Starting MS2PF from {os.getcwd()}")
 
   gen_dir = prepare_workplace(config)