From f2f6038d159bbbe5405a21c8ec004795a1167201 Mon Sep 17 00:00:00 2001
From: "mauro.trovo" <mauro.trovo@elettra.eu>
Date: Mon, 7 Apr 2025 18:14:22 +0200
Subject: [PATCH] limited solutions

---
 src/EEHGMaster.py  | 88 ++++++++++++++++++++++++++++++++++++++++------
 src/EEHGMaster.xmi | 20 +++++++++++
 2 files changed, 97 insertions(+), 11 deletions(-)

diff --git a/src/EEHGMaster.py b/src/EEHGMaster.py
index 46c5caa..db5e18a 100755
--- a/src/EEHGMaster.py
+++ b/src/EEHGMaster.py
@@ -654,6 +654,16 @@ class EEHGMaster(Device):
         doc="This is selection of R56 peak of EEHG: 0 left, 1 rigth, 2  both.",
     )
 
+    n_gold = attribute(
+        dtype='DevShort',
+        access=AttrWriteType.READ_WRITE,
+        label="N Gold",
+        max_value=-1,
+        min_value=-3,
+        memorized=True,
+        doc="Indice della soluzione preferita.",
+    )
+
     bunc_sol = attribute(
         dtype=('DevLong64',),
         max_dim_x=32,
@@ -684,6 +694,7 @@ class EEHGMaster(Device):
         self.m_value = 18
         self._n_fixed = True
         self._n_fixed = False
+        self._n_gold = -1
         self._n_solution = 0
         self._i_solution = 0
         self._lambda_fel = 12.0
@@ -1111,6 +1122,14 @@ class EEHGMaster(Device):
         self.a1.set_write_value(value)
         # PROTECTED REGION END #    //  EEHGMaster.a1_write
 
+    def is_a1_allowed(self, attr):
+        # PROTECTED REGION ID(EEHGMaster.is_a1_allowed) ENABLED START #
+        if attr==attr.READ_REQ:
+            return self.get_state() not in [DevState.RUNNING,DevState.MOVING]
+        else:
+            return self.get_state() not in [DevState.RUNNING,DevState.MOVING]
+        # PROTECTED REGION END #    //  EEHGMaster.is_a1_allowed
+
     def read_emod1(self):
         # PROTECTED REGION ID(EEHGMaster.emod1_read) ENABLED START #
         """Return the emod1 attribute."""
@@ -1135,6 +1154,14 @@ class EEHGMaster(Device):
         pass
         # PROTECTED REGION END #    //  EEHGMaster.a1_curr_write
 
+    def is_a1_curr_allowed(self, attr):
+        # PROTECTED REGION ID(EEHGMaster.is_a1_curr_allowed) ENABLED START #
+        if attr==attr.READ_REQ:
+            return True
+        else:
+            return self.get_state() not in [DevState.RUNNING,DevState.MOVING]
+        # PROTECTED REGION END #    //  EEHGMaster.is_a1_curr_allowed
+
     def read_emod1_curr(self):
         # PROTECTED REGION ID(EEHGMaster.emod1_curr_read) ENABLED START #
         """Return the emod1_curr attribute."""
@@ -1208,6 +1235,14 @@ class EEHGMaster(Device):
         pass
         # PROTECTED REGION END #    //  EEHGMaster.a2_curr_write
 
+    def is_a2_curr_allowed(self, attr):
+        # PROTECTED REGION ID(EEHGMaster.is_a2_curr_allowed) ENABLED START #
+        if attr==attr.READ_REQ:
+            return True
+        else:
+            return self.get_state() not in [DevState.RUNNING,DevState.MOVING]
+        # PROTECTED REGION END #    //  EEHGMaster.is_a2_curr_allowed
+
     def read_emod2_curr(self):
         # PROTECTED REGION ID(EEHGMaster.emod2_curr_read) ENABLED START #
         """Return the emod2_curr attribute."""
@@ -1320,6 +1355,14 @@ class EEHGMaster(Device):
         self.r561.set_write_value(value)
         # PROTECTED REGION END #    //  EEHGMaster.r561_write
 
+    def is_r561_allowed(self, attr):
+        # PROTECTED REGION ID(EEHGMaster.is_r561_allowed) ENABLED START #
+        if attr==attr.READ_REQ:
+            return True
+        else:
+            return self.get_state() not in [DevState.RUNNING,DevState.MOVING]
+        # PROTECTED REGION END #    //  EEHGMaster.is_r561_allowed
+
     def read_r561_curr(self):
         # PROTECTED REGION ID(EEHGMaster.r561_curr_read) ENABLED START #
         """Return the r561_curr attribute."""
@@ -1332,6 +1375,14 @@ class EEHGMaster(Device):
         pass
         # PROTECTED REGION END #    //  EEHGMaster.r561_curr_write
 
+    def is_r561_curr_allowed(self, attr):
+        # PROTECTED REGION ID(EEHGMaster.is_r561_curr_allowed) ENABLED START #
+        if attr==attr.READ_REQ:
+            return True
+        else:
+            return self.get_state() not in [DevState.RUNNING,DevState.MOVING]
+        # PROTECTED REGION END #    //  EEHGMaster.is_r561_curr_allowed
+
     def read_r561_fix(self):
         # PROTECTED REGION ID(EEHGMaster.r561_fix_read) ENABLED START #
         """Return the r561_fix attribute."""
@@ -1737,6 +1788,19 @@ class EEHGMaster(Device):
         pass
         # PROTECTED REGION END #    //  EEHGMaster.picco_pref_write
 
+    def read_n_gold(self):
+        # PROTECTED REGION ID(EEHGMaster.n_gold_read) ENABLED START #
+        """Return the n_gold attribute."""
+        return self._n_gold
+        # PROTECTED REGION END #    //  EEHGMaster.n_gold_read
+
+    def write_n_gold(self, value):
+        # PROTECTED REGION ID(EEHGMaster.n_gold_write) ENABLED START #
+        """Set the n_gold attribute."""
+        self._n_gold = value
+        pass
+        # PROTECTED REGION END #    //  EEHGMaster.n_gold_write
+
     def read_bunc_sol(self):
         # PROTECTED REGION ID(EEHGMaster.bunc_sol_read) ENABLED START #
         """Return the bunc_sol attribute."""
@@ -1810,7 +1874,7 @@ class EEHGMaster(Device):
 #                            wl_range = [lambda_s2_range[0]*1e-9, lambda_s2_range[1]*1e-9]) self.lambda_s2.get_properties().max_value
 
         seed2.set_duration(self._dt_s2 * 1e-15)
-        seed2.nrg_range = [0.0, self.nrg_s2_range] # andrebbe aggiustato sulla di quanto scritto nel seed master 
+        seed2.nrg_range = [0.0, self.nrg_s2_range  * 1e-6] # andrebbe aggiustato sulla di quanto scritto nel seed master 
 
         mod2.calc_aw(seed2.wl, ebeam.energy)
         
@@ -1841,7 +1905,7 @@ class EEHGMaster(Device):
         try:
             [n_sol,m_sol,wls1_sol,wls2_sol] = eehg_ora.calc_wls2_n_m(self._lambda_fel * 1e-9,
                     seed1, seed2, m_range = m_rng,
-                    n_range = n_rng, n_goal = -1, min_wls2_chg = True,
+                    n_range = n_rng, n_goal = self._n_gold, min_wls2_chg = True,
                     printout = printout)
 # 
             solu = eehg_ora.calc_eehg_conf(ebeam, n_sol, m_sol, wls1_sol, wls2_sol,
@@ -1890,25 +1954,27 @@ class EEHGMaster(Device):
         '''
         soluzione da applicare i_solution
         '''
-        A1_sol_ap = solu[0][self._i_solution] # non si applica! seed1 fixed energy
+        A1_sol_ap = solu[0][indOK[self._i_solution]] # non si applica! seed1 fixed energy
         self.write_a1(A1_sol_ap)
-        A2_sol_ap = solu[1][self._i_solution] # da convertire in energia
+        self._nrg_s1 = seed1.calc_seedpower_from_a(A1_sol_ap, ebeam, mod1, printout = printout)[1]*1e6
+        
+        A2_sol_ap = solu[1][indOK[self._i_solution]] # da convertire in energia
         self.write_a2(A2_sol_ap)
-# energia calcolata per seed2 in uJ da applicare al device sl/master/seed_master_sl.01/energy2
+        # energia calcolata per seed2 in uJ da applicare al device sl/master/seed_master_sl.01/energy2
         self._nrg_s2 = seed2.calc_seedpower_from_a(A2_sol_ap, ebeam, mod2, printout = printout)[1]*1e6 
 
-        self._r561 = (solu[2][self._i_solution] * self._r561_off_perc * 1e3
+        self._r561 = (solu[2][indOK[self._i_solution]] * self._r561_off_perc * 1e3
                       + self._r561_off_abs) # non si applica perche' r561 e' fissa
 #        R562_sol_ap = solu[3][self._i_solution] # da applicare direttamente al device fel01/magnet/dispersive_magnet_fel01.01/R56
-        self._r562 = (solu[3][self._i_solution]  * self._r562_off_perc * 1e6
+        self._r562 = (solu[3][indOK[self._i_solution]]  * self._r562_off_perc * 1e6
                       + self._r562_off_abs)
-        self._lambda_s1 = solu[4][self._i_solution] * 1e9 # non si applica! seed1 fixed wavelegth 
+        self._lambda_s1 = solu[4][indOK[self._i_solution]] * 1e9 # non si applica! seed1 fixed wavelegth 
 #        Wls2_sol_ap = solu[5][self._i_solution] # da applicare direttamente al device sl/master/seed_master_sl.01/wavelength2
-        self._lambda_s2 = solu[5][self._i_solution]  * 1e9
+        self._lambda_s2 = solu[5][indOK[self._i_solution]]  * 1e9
 #        N_so_apl = solu[6][self._i_solution] # da scivere nel server sul valore di n
-        self.write_n(solu[6][self._i_solution])
+        self.write_n(solu[6][indOK[self._i_solution]])
 #        M_sol_ap = solu[7][self._i_solution] # da scivere nel server sul valore di m
-        self.write_m(solu[7][self._i_solution])
+        self.write_m(solu[7][indOK[self._i_solution]])
 #        Bmax_sol_ap = solu[8][self._i_solution] # da scivere nel server su bunch_fel
 #        bunching_array = solu[8]
 #        print(bunching_array)
diff --git a/src/EEHGMaster.xmi b/src/EEHGMaster.xmi
index d9fc4c1..a8f010f 100644
--- a/src/EEHGMaster.xmi
+++ b/src/EEHGMaster.xmi
@@ -282,6 +282,10 @@
       <dataReadyEvent fire="false" libCheckCriteria="true"/>
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
       <properties description="A1 FEL parameter" label="A1 FEL parameter" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
+      <readExcludedStates>RUNNING</readExcludedStates>
+      <readExcludedStates>MOVING</readExcludedStates>
+      <writeExcludedStates>RUNNING</writeExcludedStates>
+      <writeExcludedStates>MOVING</writeExcludedStates>
     </attributes>
     <attributes name="emod1" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
       <dataType xsi:type="pogoDsl:DoubleType"/>
@@ -298,6 +302,8 @@
       <dataReadyEvent fire="false" libCheckCriteria="true"/>
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
       <properties description="The current values for thiese variable as read from the machine" label="a1_curr" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
+      <writeExcludedStates>RUNNING</writeExcludedStates>
+      <writeExcludedStates>MOVING</writeExcludedStates>
     </attributes>
     <attributes name="emod1_curr" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
       <dataType xsi:type="pogoDsl:DoubleType"/>
@@ -340,6 +346,8 @@
       <dataReadyEvent fire="false" libCheckCriteria="true"/>
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
       <properties description="The current values for thiese variable as read from the machine" label="a2_curr" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
+      <writeExcludedStates>RUNNING</writeExcludedStates>
+      <writeExcludedStates>MOVING</writeExcludedStates>
     </attributes>
     <attributes name="emod2_curr" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
       <dataType xsi:type="pogoDsl:DoubleType"/>
@@ -406,6 +414,8 @@
       <dataReadyEvent fire="false" libCheckCriteria="true"/>
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
       <properties description="strength of the first dispersive section used in the calculations with respect to the machine R56 it is R56 =  (R56_machine-r56_off_abs)/(1+r56_off_perc/100)" label="r561" unit="mm" standardUnit="" displayUnit="" format="" maxValue="10" minValue="0" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
+      <writeExcludedStates>RUNNING</writeExcludedStates>
+      <writeExcludedStates>MOVING</writeExcludedStates>
     </attributes>
     <attributes name="r561_curr" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
       <dataType xsi:type="pogoDsl:DoubleType"/>
@@ -414,6 +424,8 @@
       <dataReadyEvent fire="false" libCheckCriteria="true"/>
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
       <properties description="The current values for thiese variable as read from the machine" label="r561_curr" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
+      <writeExcludedStates>RUNNING</writeExcludedStates>
+      <writeExcludedStates>MOVING</writeExcludedStates>
     </attributes>
     <attributes name="r561_fix" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true" isDynamic="false">
       <dataType xsi:type="pogoDsl:BooleanType"/>
@@ -703,6 +715,14 @@
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
       <properties description="This is selection of R56 peak of EEHG: 0 left, 1 rigth, 2  both." label="picco selection" unit="" standardUnit="" displayUnit="" format="" maxValue="2" minValue="0" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
     </attributes>
+    <attributes name="n_gold" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true" isDynamic="false">
+      <dataType xsi:type="pogoDsl:ShortType"/>
+      <changeEvent fire="false" libCheckCriteria="false"/>
+      <archiveEvent fire="false" libCheckCriteria="false"/>
+      <dataReadyEvent fire="false" libCheckCriteria="true"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+      <properties description="Indice della soluzione preferita." label="N Gold" unit="" standardUnit="" displayUnit="" format="" maxValue="-1" minValue="-3" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
+    </attributes>
     <attributes name="bunc_sol" attType="Spectrum" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="32" maxY="" allocReadMember="true" isDynamic="false">
       <dataType xsi:type="pogoDsl:LongType"/>
       <changeEvent fire="false" libCheckCriteria="false"/>
-- 
GitLab