From 6f3a5c2fe04de40421b2aa3d8abab73e5cbb4e28 Mon Sep 17 00:00:00 2001 From: Gaetan Fine <fineg@ill.fr> Date: Fri, 13 May 2022 09:54:57 +0100 Subject: [PATCH] Upgraded to new way to calculate path Fixed bugs --- .gitignore | 1 + src/dummy_requester.py | 66 ++++++++------- src/path_creator.py | 141 +++++++++++++++++++++++---------- test/example_data-no_path.json | 6 +- test/example_status.json | 18 +++-- 5 files changed, 156 insertions(+), 76 deletions(-) diff --git a/.gitignore b/.gitignore index b601188..9d722f2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ logs __pycache__ log *.sublime* +*.dat \ No newline at end of file diff --git a/src/dummy_requester.py b/src/dummy_requester.py index 3864e18..0e9f0ba 100644 --- a/src/dummy_requester.py +++ b/src/dummy_requester.py @@ -7,6 +7,9 @@ import matplotlib.pyplot as plt numberOfTimes = 1 if len(sys.argv) < 3 else int(sys.argv[1]) +write = True +show = False + def process_response(raw_json): json_data = json.loads(raw_json) @@ -23,22 +26,31 @@ def process_response(raw_json): print("Error while reading response") return - print("Found a path, showing") - regions = json_data['data']['regions'] + if show: + print("Found a path, showing") + regions = json_data['data']['regions'] + + for r in regions: + plt.fill(r['x1'], r['y1'], "-", linewidth = 1., + fill = not (r['inverted'] == 'True'), + color = "#ff0000") + + x, y = zip(*vertices) + plt.xlabel("Sample Scattering Angle 2\u03b8_S (deg)") + plt.ylabel("Monochromator Scattering Angle 2\u03b8_M (deg)") + plt.plot(x, y, "-", linewidth=2) + + plt.scatter(x[0], y[0], s=15, color="green") + plt.scatter(x[-1], y[-1], s=15, color="red") + plt.show() - for r in regions: - plt.fill(r['x1'], r['y1'], "-", linewidth = 1., - fill = not (r['inverted'] == 'True'), - color = "#ff0000") + if write: + print("Found a path, writing") + with open("path_.dat", "w") as datafile: + for vertex in vertices: + datafile.write("%.4f %.4f\n" % (vertex[0], vertex[1])) - x, y = zip(*vertices) - plt.xlabel("Sample Scattering Angle 2\u03b8_S (deg)") - plt.ylabel("Monochromator Scattering Angle 2\u03b8_M (deg)") - plt.plot(x, y, "-", linewidth=2) - plt.scatter(x[0], y[0], s=15, color="green") - plt.scatter(x[-1], y[-1], s=15, color="red") - plt.show() return True elif json_data["type"] == "ok": print("Done.\n") @@ -79,19 +91,19 @@ response = requester.receiveString() process_response(response) -print("setup builder") -f = open('test/example_builder-options.json') -request = f.read() -f.close() -requester.send(request) -response = requester.receiveString() -process_response(response) +# print("setup builder") +# f = open('test/example_builder-options.json') +# request = f.read() +# f.close() +# requester.send(request) +# response = requester.receiveString() +# process_response(response) -print("working data") -f = open('test/example_data-working.json') -request = f.read() -f.close() -requester.send(request) -response = requester.receiveString() -process_response(response) \ No newline at end of file +# print("working data") +# f = open('test/example_data-working.json') +# request = f.read() +# f.close() +# requester.send(request) +# response = requester.receiveString() +# process_response(response) \ No newline at end of file diff --git a/src/path_creator.py b/src/path_creator.py index 5a7c430..35fc160 100644 --- a/src/path_creator.py +++ b/src/path_creator.py @@ -1,5 +1,14 @@ #!/usr/bin/python3 +#################################################### +# TODO +# +# SetSampleAngleOffset ? +# ScatteringSense ? +# +# +#################################################### + import sys import os import math as m @@ -76,6 +85,9 @@ ERROR = None # The crystal config and instrument config current_crystal_config = { + "sense0" : None, + "sense1" : None, + "sense2" : None, "sampleLatticeConstantA": None, "sampleLatticeConstantB": None, "sampleLatticeConstantC": None, @@ -88,6 +100,7 @@ current_crystal_config = { "sampleScatteringPlaneBx" : None, "sampleScatteringPlaneBy" : None, "sampleScatteringPlaneBz" : None, + "setSampleAngleOffset" : None } current_instrument_config = { @@ -128,6 +141,7 @@ parser.add_argument('--instr-space', metavar='INSTRUMENT_SPACE_FILE') argv = None + if sys.argv[-1][0] != '{': warning('Must be run from a cameo server') argv = sys.argv[1:] @@ -151,7 +165,10 @@ logging.basicConfig(filename=args.log_dir + os.sep + log_file, level=args.log_le def setup_crystal(data): global tascalc - tascalc.SetScatteringSenses(True, False, True) + debug("Setting up tascalc crystal configuration with :{}".format(str(data))) + + + tascalc.SetScatteringSenses(data["sense0"] >= 0., data["sense1"] >= 0., data["sense2"] >= 0.) tascalc.SetSampleLatticeConstants(float(data["sampleLatticeConstantA"]), float(data["sampleLatticeConstantB"]), @@ -168,6 +185,11 @@ def setup_crystal(data): float(data["sampleScatteringPlaneBx"]), float(data["sampleScatteringPlaneBy"]), float(data["sampleScatteringPlaneBz"])) + + if data["setSampleAngleOffset"] == 1: + tascalc.SetSampleAngleOffset(90./180.*m.pi) + + tascalc.UpdateB() tascalc.UpdateUB() @@ -196,12 +218,8 @@ def init(): info("Instrument definition loaded.\n") # ----------------------------------------------------------------------------- - # ----------------------------------------------------------------------------- - # Set-up a sample single-crystal - # ----------------------------------------------------------------------------- - + tascalc = tas.TasCalculator() - # setup_crystal(current_crystal_config) # ----------------------------------------------------------------------------- return True @@ -217,15 +235,18 @@ def build_mesh(): warning("You must set Kf or Ki to be fixed before calculating mesh") return False - if current_instrument_config["fixedAngle"] == "Kf": - tascalc.SetKf(1.4) - else: - tascalc.SetKi(1.4) # ----------------------------------------------------------------------------- # Create path builder # ----------------------------------------------------------------------------- builder = tas.PathsBuilder() + + if current_instrument_config["fixedAngle"] == "Kf": + tascalc.SetKf(1.4) + else: + tascalc.SetKi(1.4) + + builder.AddConsoleProgressHandler() builder.SetInstrumentSpace(instrspace) #builder.SetScatteringSenses(senses) @@ -236,21 +257,33 @@ def build_mesh(): # Build path mesh # ----------------------------------------------------------------------------- + # angular ranges to probe - angle_padding = 4. - a2_delta = 1./180.*m.pi # if mode is ki fixed a2 is a6 - a4_delta = 2./180.*m.pi - a2_begin = 0. - angle_padding*a2_delta - a2_end = m.pi + angle_padding*a2_delta - a4_begin = -m.pi - angle_padding*a4_delta - a4_end = m.pi + angle_padding*a4_delta + if current_instrument_config["fixedAngle"] == "Kf": + angle_padding = 4. + + analyzer_delta = 2./180.*m.pi + analyzer_begin = -m.pi - angle_padding*analyzer_delta + analyzer_end = m.pi + angle_padding*analyzer_delta + + free_part_delta = 1./180.*m.pi + free_part_begin = 0. - angle_padding*free_part_delta + free_part_end = m.pi + angle_padding*free_part_delta + else: + free_part_delta = 4./180.*m.pi + analyzer_delta = 4./180.*m.pi + free_part_begin = -m.pi + free_part_end = m.pi + analyzer_begin = -m.pi + analyzer_end = m.pi + builder.StartPathMeshWorkflow() if not builder.CalculateConfigSpace( - a2_delta, a4_delta, - a2_begin, a2_end, - a4_begin, a4_end): + free_part_delta, analyzer_delta, + free_part_begin, free_part_end, + analyzer_begin, analyzer_end): critical("Angular configuration space could not be calculated.") return False @@ -281,21 +314,29 @@ def calculate_path(target_angles): global builder - target_angles.monoXtalAngle = abs(target_angles.monoXtalAngle) - target_angles.sampleXtalAngle = abs(target_angles.sampleXtalAngle) - target_angles.sampleScatteringAngle = abs(target_angles.sampleScatteringAngle) + if current_instrument_config["fixedAngle"] == "Kf": + debug("Using fixed Kf path building") + target_angles.monoXtalAngle = target_angles.monoXtalAngle * current_crystal_config["sense0"] + else: + debug("Using fixed Ki path building") + target_angles.anaXtalAngle = target_angles.anaXtalAngle * current_crystal_config["sense2"] + + - info("Start angles: a1 = %.2f deg, a5 = %.2f deg, a3 = %.2f deg, a4 = %.2f deg." % ( - float(current_instrument_config["monoXtalAngle"]) / m.pi*180., - float(current_instrument_config["anaXtalAngle"]) / m.pi*180., - float(current_instrument_config["sampleXtalAngle"]) / m.pi*180., - float(current_instrument_config["sampleScatteringAngle"]) / m.pi*180.)) + target_angles.sampleXtalAngle = target_angles.sampleXtalAngle * current_crystal_config["sense1"] + target_angles.sampleScatteringAngle = target_angles.sampleScatteringAngle * current_crystal_config["sense1"] - info("Target angles: a1 = %.2f deg, a5 = %.2f deg, a3 = %.2f deg, a4 = %.2f deg." % ( - target_angles.monoXtalAngle / m.pi*180., - target_angles.anaXtalAngle / m.pi*180., - target_angles.sampleXtalAngle / m.pi*180., - target_angles.sampleScatteringAngle / m.pi*180.)) + info("Start angles: a1 = %.2f rad, a5 = %.2f rad, a3 = %.2f rad, a4 = %.2f rad." % ( + float(current_instrument_config["monoXtalAngle"]), + float(current_instrument_config["anaXtalAngle"]), + float(current_instrument_config["sampleXtalAngle"]), + float(current_instrument_config["sampleScatteringAngle"]))) + + info("Target angles: a1 = %.2f rad, a5 = %.2f rad, a3 = %.2f rad, a4 = %.2f rad." % ( + target_angles.monoXtalAngle, + target_angles.anaXtalAngle, + target_angles.sampleXtalAngle, + target_angles.sampleScatteringAngle)) # ----------------------------------------------------------------------------- @@ -304,14 +345,15 @@ def calculate_path(target_angles): # ----------------------------------------------------------------------------- path = None + if current_instrument_config["fixedAngle"] == "Kf": path = builder.FindPath( - float(current_instrument_config["monoScatteringAngle"]), float(current_instrument_config["sampleScatteringAngle"]), + float(current_instrument_config["monoXtalAngle"]) * 2, float(current_instrument_config["sampleScatteringAngle"]), target_angles.monoXtalAngle * 2., target_angles.sampleScatteringAngle, tas.PathStrategy_PENALISE_WALLS) else: path = builder.FindPath( - float(current_instrument_config["anaScatteringAngle"]), float(current_instrument_config["sampleScatteringAngle"]), + float(current_instrument_config["anaXtalAngle"])* 2., float(current_instrument_config["sampleScatteringAngle"]), target_angles.anaXtalAngle * 2., target_angles.sampleScatteringAngle, tas.PathStrategy_PENALISE_WALLS) @@ -368,6 +410,11 @@ def write_json_path_data(vertices): def update_crystal(data): global current_crystal_config + if len(data.keys()) != 16: + setError(INCONSISTENT_DATA, "Missing or too many value in crystal configuration") + warning("Missing value in crystal configuration") + return False + # Ensuring data is consistent for key in data.keys(): if key not in current_crystal_config or \ @@ -382,6 +429,13 @@ def update_crystal(data): # Re do the crystal setup setup_crystal(current_crystal_config) + + # if not build_mesh(): + # setError(CRITICAL_CANT_BUILD_MESH) + # warning("Couldn't build mesh") + # ready = False + # return False + return True @@ -407,8 +461,8 @@ def update_instr(data): # More verification on consistency if 2* data["monoXtalAngle"] != data["monoScatteringAngle"] or\ 2* data["anaXtalAngle"] != data["anaScatteringAngle"] : - setError(INCONSISTENT_DATA, "Instrument configuration data is inconsistent\nMonochromator and Analyser axis angles must be 2 times crystal angles") - warning("Instrument configuration data is inconsistent\nMonochromator and Analyser axis angles must be 2 times crystal angles") + setError(INCONSISTENT_DATA, "Instrument configuration data is inconsistent\nMonochromator and Analyzer axis angles must be 2 times crystal angles") + warning("Instrument configuration data is inconsistent\nMonochromator and Analyzer axis angles must be 2 times crystal angles") return False if data["fixedAngle"] != "Kf" and data["fixedAngle"] != "Ki": @@ -507,7 +561,8 @@ while True: if request: info('Reveived request') - debug("Current instrument state : " + str(current_crystal_config)) + debug("Current crystal state : " + str(current_crystal_config)) + debug("Current instrument state : " + str(current_instrument_config)) vertices = None # Try to read the request data try: @@ -524,12 +579,16 @@ while True: if data[0] == "path": # Always need a first setup to get the instrument state if not ready: + warning("Setup is needed before calculating path\n") setError(SETUP_NEEDED) reply(request, ERROR) continue target_angles = data[1]["targetAngles"] - target_angles = tascalc.GetAngles( float( target_angles["h"]), -0.5, 0., float( target_angles["E"])) + target_angles = tascalc.GetAngles( float( target_angles["h"]), + float( target_angles["k"]), + float( target_angles["l"]), + float( target_angles["E"])) # Calculate the path vertices = calculate_path(target_angles) @@ -548,13 +607,15 @@ while True: info("Updated crystal state\n") else: reply(request, ERROR) + continue # Instrument state if "instrument" in data[1]: if update_instr(data[1]["instrument"]): - info("Updated crystal instrument\n") + info("Updated instrument state\n") else: reply(request, ERROR) + continue reply(request, OK_REPLY) if is_ready(): diff --git a/test/example_data-no_path.json b/test/example_data-no_path.json index eec4aed..5b3e553 100644 --- a/test/example_data-no_path.json +++ b/test/example_data-no_path.json @@ -2,8 +2,10 @@ "type": "path", "data" : { "targetAngles" : { - "h" : 1.5, - "E" : 2.5 + "h" : 1, + "k" : 1, + "l" : 0, + "E" : 1.2 } } } \ No newline at end of file diff --git a/test/example_status.json b/test/example_status.json index 6368fcc..ba6ab90 100644 --- a/test/example_status.json +++ b/test/example_status.json @@ -3,6 +3,9 @@ "data": { "crystal" : { + "sense0" : -1, + "sense1" : 1, + "sense2" : -1, "sampleLatticeConstantA": 5, "sampleLatticeConstantB": 5, "sampleLatticeConstantC": 5, @@ -14,15 +17,16 @@ "sampleScatteringPlaneAz" : 0, "sampleScatteringPlaneBx" : 0, "sampleScatteringPlaneBy" : 1, - "sampleScatteringPlaneBz" : 0 + "sampleScatteringPlaneBz" : 0, + "setSampleAngleOffset" : 1 }, "instrument" : { - "monoXtalAngle" : 0.785398, - "monoScatteringAngle" : 1.570796, - "sampleXtalAngle" : 0.785398, - "sampleScatteringAngle" : -1.570796, - "anaXtalAngle" : 0.785398, - "anaScatteringAngle" : 1.570796, + "monoXtalAngle" : -0.732662, + "monoScatteringAngle" : -1.465324, + "sampleXtalAngle" : 0.677828, + "sampleScatteringAngle" : 1.012062, + "anaXtalAngle" : 0.946123, + "anaScatteringAngle" : 1.892246, "fixedAngle": "Ki" } } -- GitLab