def testConfiguration(self):
        channel = 'masarService'
        self.mc = masarClient.client(channelname=channel)
        # DB SETUP
        self.conn, collection = utils.conn(
            host=masarconfig.get('mongodb', 'host'),
            port=masarconfig.get('mongodb', 'port'),
            db=masarconfig.get('mongodb', 'database'))

        self.conn.drop_database(masarconfig.get('mongodb', 'database'))
        name = "SR_All_20140421"
        test_status = 'active'
        test_version = 20140421
        test_system = 'SR'
        test_desc = "SR daily SCR setpoint without IS kick and septum: SR and RF"
        params = {
            "desc": test_desc,
            "system": test_system,
            "status": test_status,
            "version": test_version,
        }
        newid = saveconfig(self.conn, collection, name, **params)
        self.assertNotEqual(None, newid)
        res0 = retrieveconfig(self.conn, collection, name)
        self.assertEqual(test_status, res0[0]['status'])
        self.assertEqual(1, res0[0]['configidx'])
        self.assertEqual(name, res0[0]['name'])
        self.assertEqual(test_system, res0[0]['system'])
        self.assertNotEqual(None, res0[0]['created_on'])
        # The following 2 tests are to confirm the date string is in the correct format
        self.assertEqual(3, len(res0[0]['created_on'].split('-')))
        self.assertEqual(3, len(res0[0]['created_on'].split(':')))
        self.assertEqual(test_version, res0[0]['version'])
        self.assertEqual(test_desc, res0[0]['desc'])
        pvs = ["masarExampleDoubleArray"]
        pvlist = {"names": pvs}
        res = updateconfig(self.conn, collection, name, pvlist=pvlist)
        self.assertEqual(True, res)
        res3 = retrieveconfig(self.conn, collection, name, withpvs=True)
        self.assertEqual(test_status, res3[0]['status'])
        self.assertEqual(1, res3[0]['configidx'])
        self.assertEqual(name, res3[0]['name'])
        self.assertEqual(test_system, res3[0]['system'])
        self.assertNotEqual(None, res3[0]['created_on'])
        # The following 2 tests are to confirm the date string is in the correct format
        self.assertEqual(3, len(res3[0]['created_on'].split('-')))
        self.assertEqual(3, len(res3[0]['created_on'].split(':')))
        self.assertEqual(test_version, res3[0]['version'])
        self.assertEqual(test_desc, res3[0]['desc'])
        self.assertEqual(pvlist, res3[0]['pvlist'])
        self.assertNotEqual(None, res3[0]['updated_on'])
        # The following 2 tests are to confirm the date string is in the correct format
        self.assertEqual(3, len(res3[0]['updated_on'].split('-')))
        self.assertEqual(3, len(res3[0]['updated_on'].split(':')))
        # drop DB
        self.conn.drop_database(masarconfig.get('mongodb', 'database'))
        utils.close(self.conn)
    def testConfiguration(self):
        channel = 'masarService'
        self.mc = masarClient.client(channelname=channel)
        # DB SETUP
        self.conn, collection = utils.conn(host=masarconfig.get('mongodb', 'host'),
                                           port=masarconfig.get('mongodb', 'port'),
                                           db=masarconfig.get('mongodb', 'database'))

        self.conn.drop_database(masarconfig.get('mongodb', 'database'))
        name = "SR_All_20140421"
        test_status = 'active'
        test_version = 20140421
        test_system = 'SR'
        test_desc = "SR daily SCR setpoint without IS kick and septum: SR and RF"
        params = {"desc": test_desc,
                  "system": test_system,
                  "status": test_status,
                  "version": test_version,
                  }
        newid = saveconfig(self.conn, collection, name, **params)
        self.assertNotEqual(None, newid)
        res0 = retrieveconfig(self.conn, collection, name)
        self.assertEqual(test_status, res0[0]['status'])
        self.assertEqual(1, res0[0]['configidx'])
        self.assertEqual(name, res0[0]['name'])
        self.assertEqual(test_system, res0[0]['system'])
        self.assertNotEqual(None, res0[0]['created_on'])
        # The following 2 tests are to confirm the date string is in the correct format
        self.assertEqual(3, len(res0[0]['created_on'].split('-')))
        self.assertEqual(3, len(res0[0]['created_on'].split(':')))
        self.assertEqual(test_version, res0[0]['version'])
        self.assertEqual(test_desc, res0[0]['desc'])
        pvs = ["masarExampleDoubleArray"]
        pvlist = {"names": pvs}
        res = updateconfig(self.conn, collection, name, pvlist=pvlist)
        self.assertEqual(True, res)
        res3 = retrieveconfig(self.conn, collection, name, withpvs=True)
        self.assertEqual(test_status, res3[0]['status'])
        self.assertEqual(1, res3[0]['configidx'])
        self.assertEqual(name, res3[0]['name'])
        self.assertEqual(test_system, res3[0]['system'])
        self.assertNotEqual(None, res3[0]['created_on'])
        # The following 2 tests are to confirm the date string is in the correct format
        self.assertEqual(3, len(res3[0]['created_on'].split('-')))
        self.assertEqual(3, len(res3[0]['created_on'].split(':')))
        self.assertEqual(test_version, res3[0]['version'])
        self.assertEqual(test_desc, res3[0]['desc'])
        self.assertEqual(pvlist, res3[0]['pvlist'])
        self.assertNotEqual(None,res3[0]['updated_on'])
        # The following 2 tests are to confirm the date string is in the correct format
        self.assertEqual(3, len(res3[0]['updated_on'].split('-')))
        self.assertEqual(3, len(res3[0]['updated_on'].split(':')))
        # drop DB
        self.conn.drop_database(masarconfig.get('mongodb', 'database'))
        utils.close(self.conn)
 def testUpdateMasarConfigStatus(self):
     app = QtGui.QApplication(sys.argv)
     ui = dbmanagerUI()
     ui.dbsource = 1  # Called normally with menu selection
     ui.defaultmongodb()
     masarconf = 'SR_All_20140421'
     conn, collection = utils.conn(host=masarconfig.get('mongodb', 'host'),
                                        port=masarconfig.get('mongodb', 'port'),
                                        db=masarconfig.get('mongodb', 'database'))
     ui.updatemasarconfigstatus("inactive", 1)
     res3 = retrieveconfig(conn, collection, masarconf, withpvs=True)
     self.assertEqual("inactive", res3[0]['status'])
     ui.updatemasarconfigstatus("active",1)
     res3 = retrieveconfig(conn, collection, masarconf, withpvs=True)
     self.assertEqual("active", res3[0]['status'])
Exemple #4
0
 def testRetrieveSnapshot(self):
     name = 'SR-All-20140326'
     test_comment = "test"
     test_approval = True
     test_username = "******"
     test_masar_data = [0]
     params = {
         "desc": "SR daily SCR setpoint: SR and IS PS, RF",
         "system": "SR",
         "status": "inactive",
         "version": 20140326,
     }
     newid = saveconfig(self.conn, self.collection, name, **params)
     new = retrieveconfig(self.conn, self.collection, name=name)
     self.assertEqual(len(new), 1,
                      "Should find only one entry instead of %s" % len(new))
     configidx = new[0]["configidx"]
     eventid = saveevent(self.conn,
                         self.collection,
                         configidx=configidx,
                         comment=test_comment,
                         approval=test_approval,
                         masar_data=test_masar_data,
                         username=test_username)
     self.assertNotEqual(eventid, None)
     result = retrievesnapshot(self.conn, self.collection, eventidx=eventid)
     self.assertEqual(result["eventidx"], eventid)
     self.assertEqual(result["configidx"], configidx)
     self.assertEqual(result["comment"], test_comment)
     self.assertEqual(result["approval"], test_approval)
     self.assertEqual(result["username"], test_username)
     self.assertEqual(result["masar_data"], test_masar_data)
Exemple #5
0
    def retrieveChannelNames(self, params):
        """Retrieve PV name list of given configuration(s).

        :param params: a dictionary to carry query condition with structure like: ::

            {"configname": , # configuration name, wildcast allowed with * for multiple characters matching
            }

        :returns: list of pv name like: ::

            [pv1, pv2, ...]

        :raises: ValueError

        """
        key = ['configname',  "comment"]
        config, _ = self._parseParams(params, key)

        if config is not None:
            mongoconn, collection = utils.conn(host=os.environ["MASAR_MONGO_HOST"],
                                               port=os.environ["MASAR_MONGO_PORT"],
                                               db=os.environ["MASAR_MONGO_DB"])
            result = pymasar.retrieveconfig(mongoconn, collection, name=config, withpvs=True)
            utils.close(mongoconn)
        else:
            raise ValueError("Known configuration name.")

        results = []
        for res in result:
            results = results + res["pvlist"]["names"]

        return results
 def testUpdateMasarConfigStatus(self):
     app = QtGui.QApplication(sys.argv)
     ui = dbmanagerUI()
     ui.dbsource = 1  # Called normally with menu selection
     ui.defaultmongodb()
     masarconf = 'SR_All_20140421'
     conn, collection = utils.conn(host=masarconfig.get('mongodb', 'host'),
                                   port=masarconfig.get('mongodb', 'port'),
                                   db=masarconfig.get(
                                       'mongodb', 'database'))
     ui.updatemasarconfigstatus("inactive", 1)
     res3 = retrieveconfig(conn, collection, masarconf, withpvs=True)
     self.assertEqual("inactive", res3[0]['status'])
     ui.updatemasarconfigstatus("active", 1)
     res3 = retrieveconfig(conn, collection, masarconf, withpvs=True)
     self.assertEqual("active", res3[0]['status'])
 def testRetrieveSnapshot(self):
     name = 'SR-All-20140326'
     test_comment = "test"
     test_approval = True
     test_username = "******"
     test_masar_data = [0]
     params = {"desc": "SR daily SCR setpoint: SR and IS PS, RF",
               "system": "SR",
               "status": "inactive",
               "version": 20140326,
               }
     newid = saveconfig(self.conn, self.collection, name, **params)
     new = retrieveconfig(self.conn, self.collection, name=name)
     self.assertEqual(len(new), 1,
                      "Should find only one entry instead of %s" % len(new))
     configidx = new[0]["configidx"]
     eventid = saveevent(self.conn,
                         self.collection,
                         configidx=configidx,
                         comment=test_comment,
                         approval=test_approval,
                         masar_data=test_masar_data,
                         username=test_username)
     self.assertNotEqual(eventid, None)
     result = retrievesnapshot(self.conn,
                               self.collection,
                               eventidx=eventid)
     self.assertEqual(result["eventidx"], eventid)
     self.assertEqual(result["configidx"], configidx)
     self.assertEqual(result["comment"], test_comment)
     self.assertEqual(result["approval"], test_approval)
     self.assertEqual(result["username"], test_username)
     self.assertEqual(result["masar_data"], test_masar_data)
Exemple #8
0
    def retrieveServiceConfigs(self, params):
        """Retrieve configurations

        :param params: a dictionary to carry query condition with structure like: ::

            {"configname": [optional], # configuration name, wildcast allowed with * for multiple characters matching
             "system": [optional], # system name, wildcast allowed with * for multiple characters matching
             "configversion": [optional], # configuration version number
             "status": [optional], # either active or inactive, otherwise reset to None
            }

            or {'eventid': , # event index number to get which configuration this event belongs to}

        :returns: list with tuple with header description for each field. Structure like: ::

            [('config_idx', 'config_name', 'config_desc', 'config_create_date', 'config_version', 'status'), ...]

        :raises:

        """
        key = ['configname', 'configversion', 'system', 'status', 'eventid']
        configname, version, system, status, eventid = self._parseParams(params, key)
        if isinstance(eventid, (str, unicode)):
            eventid = int(eventid)
        if status is not None:
            status = status.lower()
            if status not in ["active", "inactive"]:
                status = None
        if system is not None and system.lower() == "all":
                system = None
        mongoconn, collection = utils.conn(host=os.environ["MASAR_MONGO_HOST"],
                                           port=os.environ["MASAR_MONGO_PORT"],
                                           db=os.environ["MASAR_MONGO_DB"])
        if eventid is not None:
            result = pymasar.retrieveconfig(mongoconn, collection, eventidx=eventid)
        elif system is None and configname is None:
            result = pymasar.retrieveconfig(mongoconn, collection, status=status)
        elif system is None:
            result = pymasar.retrieveconfig(mongoconn, collection, name=configname, status=status)
        else:
            result = pymasar.retrieveconfig(mongoconn, collection, system=system, status=status)
        utils.close(mongoconn)
        results = [('config_idx', 'config_name', 'config_desc', 'config_create_date', 'config_version', 'status')]
        for res in result:
            results.append((res["configidx"], res["name"], res["desc"], res["created_on"], res["version"], res["status"]))

        return results
Exemple #9
0
    def testSaveEvents(self):
        name = 'SR-All-20140326'
        params = {
            "desc": "SR daily SCR setpoint: SR and IS PS, RF",
            "system": "SR",
            "status": "inactive",
            "version": 20140326,
        }
        newid = saveconfig(self.conn, self.collection, name, **params)
        new = retrieveconfig(self.conn, self.collection, name=name)
        self.assertEqual(len(new), 1,
                         "Should find only one entry instead of %s" % len(new))
        configidx = new[0]["configidx"]

        with self.assertRaises(RuntimeError) as context:
            eventid = saveevent(self.conn,
                                self.collection,
                                configidx=configidx,
                                comment="good snapshot",
                                approval=True,
                                masar_data=None,
                                username="******")
        self.assertEqual(context.exception.message,
                         "Data set can not be empty.")

        with self.assertRaises(RuntimeError) as context:
            eventid = saveevent(self.conn,
                                self.collection,
                                configidx=None,
                                comment="good snapshot",
                                approval=True,
                                masar_data=["element"],
                                username="******")
        self.assertEqual(context.exception.message,
                         "Cannot identify configuration index number.")

        with self.assertRaises(ValueError) as context:
            eventid = saveevent(self.conn,
                                self.collection,
                                configidx=-1,
                                comment="good snapshot",
                                approval=True,
                                masar_data=["element"],
                                username="******")
        self.assertEqual(context.exception.message,
                         "Unknown configuration index number (%s)" % str(-1))

        eventid = saveevent(self.conn,
                            self.collection,
                            configidx=configidx,
                            comment="good snapshot",
                            approval=True,
                            masar_data=["element"],
                            username="******")
        self.assertNotEqual(eventid, None)
    def testSaveEvents(self):
        name = 'SR-All-20140326'
        params = {"desc": "SR daily SCR setpoint: SR and IS PS, RF",
                  "system": "SR",
                  "status": "inactive",
                  "version": 20140326,
                  }
        newid = saveconfig(self.conn, self.collection, name, **params)
        new = retrieveconfig(self.conn, self.collection, name=name)
        self.assertEqual(len(new), 1,
                         "Should find only one entry instead of %s"%len(new))
        configidx = new[0]["configidx"]

        with self.assertRaises(RuntimeError) as context:
            eventid = saveevent(self.conn,
                                self.collection,
                                configidx=configidx,
                                comment="good snapshot",
                                approval=True,
                                masar_data=None,
                                username="******")
        self.assertEqual(context.exception.message, "Data set can not be empty.")

        with self.assertRaises(RuntimeError) as context:
            eventid = saveevent(self.conn,
                                self.collection,
                                configidx=None,
                                comment="good snapshot",
                                approval=True,
                                masar_data=["element"],
                                username="******")
        self.assertEqual(context.exception.message, "Cannot identify configuration index number.")

        with self.assertRaises(ValueError) as context:
            eventid = saveevent(self.conn,
                                self.collection,
                                configidx=-1,
                                comment="good snapshot",
                                approval=True,
                                masar_data=["element"],
                                username="******")
        self.assertEqual(context.exception.message, "Unknown configuration index number (%s)" % str(-1))

        eventid = saveevent(self.conn,
                            self.collection,
                            configidx=configidx,
                            comment="good snapshot",
                            approval=True,
                            masar_data=["element"],
                            username="******")
        self.assertNotEqual(eventid, None)
Exemple #11
0
    def retrieveSystems(self, params):
        """Retrieve system list

        :param params: a dictionary to carry query condition with structure like: ::

            {"system": [optional], # system name, wildcast allowed with * for multiple characters matching
             "configname": [optional], # configuration name, wildcast allowed with * for multiple characters matching
            }

        :returns: list with tuple with header description for each field. Structure like: ::

            [('config_id', 'config_idx', 'system_key', 'system_val'), ...]

        :raises:

        """
        key = ['system', 'configname']
        system, configname = self._parseParams(params, key)

        mongoconn, collection = utils.conn(host=os.environ["MASAR_MONGO_HOST"],
                                           port=os.environ["MASAR_MONGO_PORT"],
                                           db=os.environ["MASAR_MONGO_DB"])
        if system is None and configname is None:
            result = pymasar.retrieveconfig(mongoconn, collection)
        elif system is None:
            result = pymasar.retrieveconfig(mongoconn, collection, name=configname)
        else:
            if system.lower() == "all":
                result = pymasar.retrieveconfig(mongoconn, collection)
            else:
                result = pymasar.retrieveconfig(mongoconn, collection, system=system)
        utils.close(mongoconn)
        results = [('config_prop_id', 'config_idx', 'system_key', 'system_val')]
        for res in result:
            results.append((int(str(res["_id"]), 16), res["configidx"], "system", res["system"]))

        return results
 def testSaveMasarMongoDB(self):
     app = QtGui.QApplication(sys.argv)
     ui = dbmanagerUI()
     ui.dbsource = 1  # Called normally with menu selection
     ui.defaultmongodb()
     ui.test_in_progress_flag = 1
     ui.savemasarmongodb()
     masarconf = 'newcfgname'
     conn, collection = utils.conn(host=masarconfig.get('mongodb', 'host'),
                                        port=masarconfig.get('mongodb', 'port'),
                                        db=masarconfig.get('mongodb', 'database'))
     res3 = retrieveconfig(conn, collection, masarconf, withpvs=True)
     self.assertEqual('newcfgname', res3[0]['name'])
     self.assertEqual('newmsystem', res3[0]['system'])
     self.assertEqual('newcfgdesc', res3[0]['desc'])
 def testSaveMasarMongoDB(self):
     app = QtGui.QApplication(sys.argv)
     ui = dbmanagerUI()
     ui.dbsource = 1  # Called normally with menu selection
     ui.defaultmongodb()
     ui.test_in_progress_flag = 1
     ui.savemasarmongodb()
     masarconf = 'newcfgname'
     conn, collection = utils.conn(host=masarconfig.get('mongodb', 'host'),
                                   port=masarconfig.get('mongodb', 'port'),
                                   db=masarconfig.get(
                                       'mongodb', 'database'))
     res3 = retrieveconfig(conn, collection, masarconf, withpvs=True)
     self.assertEqual('newcfgname', res3[0]['name'])
     self.assertEqual('newmsystem', res3[0]['system'])
     self.assertEqual('newcfgdesc', res3[0]['desc'])
Exemple #14
0
 def testUpdateEvents(self):
     name = 'SR-All-20140326'
     test_comment = "test"
     updated_comment = "updated"
     test_approval = True
     updated_approval = False
     test_username = "******"
     updated_username = "******"
     test_masar_data = [0]
     params = {
         "desc": "SR daily SCR setpoint: SR and IS PS, RF",
         "system": "SR",
         "status": "inactive",
         "version": 20140326,
     }
     newid = saveconfig(self.conn, self.collection, name, **params)
     new = retrieveconfig(self.conn, self.collection, name=name)
     self.assertEqual(len(new), 1,
                      "Should find only one entry instead of %s" % len(new))
     configidx = new[0]["configidx"]
     eventid = saveevent(self.conn,
                         self.collection,
                         configidx=configidx,
                         comment=test_comment,
                         approval=test_approval,
                         masar_data=test_masar_data,
                         username=test_username)
     self.assertNotEqual(eventid, None)
     with self.assertRaises(RuntimeError) as context:
         result = updateevent(self.conn,
                              self.collection,
                              configidx=None,
                              comment=updated_comment,
                              approval=updated_approval,
                              username=updated_username)
     self.assertEqual(context.exception.message,
                      "Unknown MASAR event to update.")
     with self.assertRaises(RuntimeError) as context:
         result = updateevent(self.conn, self.collection, eventidx=eventid)
     self.assertEqual(context.exception.message, "No fields to update.")
     result = updateevent(self.conn,
                          self.collection,
                          eventidx=eventid,
                          comment=updated_comment,
                          approval=updated_approval,
                          username=updated_username)
     self.assertTrue(result)
 def testUpdateEvents(self):
     name = 'SR-All-20140326'
     test_comment = "test"
     updated_comment = "updated"
     test_approval = True
     updated_approval = False
     test_username = "******"
     updated_username = "******"
     test_masar_data = [0]
     params = {"desc": "SR daily SCR setpoint: SR and IS PS, RF",
               "system": "SR",
               "status": "inactive",
               "version": 20140326,
               }
     newid = saveconfig(self.conn, self.collection, name, **params)
     new = retrieveconfig(self.conn, self.collection, name=name)
     self.assertEqual(len(new), 1,
                      "Should find only one entry instead of %s" % len(new))
     configidx = new[0]["configidx"]
     eventid = saveevent(self.conn,
                         self.collection,
                         configidx=configidx,
                         comment=test_comment,
                         approval=test_approval,
                         masar_data=test_masar_data,
                         username=test_username)
     self.assertNotEqual(eventid, None)
     with self.assertRaises(RuntimeError) as context:
         result = updateevent(self.conn,
                              self.collection,
                              configidx=None,
                              comment=updated_comment,
                              approval=updated_approval,
                              username=updated_username)
     self.assertEqual(context.exception.message, "Unknown MASAR event to update.")
     with self.assertRaises(RuntimeError) as context:
         result = updateevent(self.conn,
                              self.collection,
                              eventidx=eventid)
     self.assertEqual(context.exception.message, "No fields to update.")
     result = updateevent(self.conn,
                          self.collection,
                          eventidx=eventid,
                          comment=updated_comment,
                          approval=updated_approval,
                          username=updated_username)
     self.assertTrue(result)
 def testSaveMongoServiceConfigs(self):
     conn, collection = utils.conn(host=masarconfig.get('mongodb', 'host'), port=masarconfig.get('mongodb', 'port'),
     db=masarconfig.get('mongodb', 'database'))
     conn.drop_database(masarconfig.get('mongodb', 'database'))
     saveMongoService(self.parsed_json)
     res3 = retrieveconfig(conn, collection, 'BR_MG_SCR_20130419', withpvs=True)
     self.assertEqual(res3[0]['status'], 'active')
     self.assertEqual('BR_MG_SCR_20130419', res3[0]['name'])
     self.assertEqual(res3[0]['pvlist']['names'], [u'masarExample0000', u'masarExample0001', u'masarExampleBoUninit', u'masarExampleMbboUninit', u'masarExample0002', u'masarExample0003', u'masarExample0004', u'masarExampleCharArray', u'masarExampleShortArray', u'masarExampleLongArray', u'masarExampleStringArray', u'masarExampleFloatArray', u'masarExampleDoubleArray', u'masarExampleMbboUninitTest'])
     self.assertEqual('BR', res3[0]['system'])
     self.assertEqual(3, len(res3[0]['created_on'].split('-')))  # Date format test
     self.assertEqual(3, len(res3[0]['created_on'].split(':')))  # 2016-07-28 18:18:36
     self.assertEqual(None, res3[0]['version'])
     self.assertEqual(3, len(res3[0]['updated_on'].split('-')))  # Date format test
     self.assertEqual(3, len(res3[0]['updated_on'].split(':')))  # 2016-07-28 18:18:36
     self.assertNotEqual(None, res3[0]['_id'])
     self.assertEqual('BR ramping PS daily SCR setpoint', res3[0]['desc'])
Exemple #17
0
    def retrieveSnapshot(self, params):
        """Retrieve snapshot data

        :param params: a dictionary to carry query condition with structure like: ::

            {"eventid": , # event index number}

        :returns: 2-d list with tuple with header description for each field. Structure like: ::

            [[('user tag', 'event time', 'service config name', 'service name'),
              ('pv name', 'string value', 'double value', 'long value', 'dbr type', 'isConnected',
               'secondsPastEpoch', 'nanoSeconds', 'timeStampTag', 'alarmSeverity', 'alarmStatus', 'alarmMessage',
               'is_array', 'array_value')], # header information to determine returning data
             [(comment, date, config name, None),
              (value for pv1 as described above),
              (value for pv2),
              ...]

        :raises:

        """
        key = ['eventid', 'comment']
        eid, _ = self._parseParams(params, key)
        result = [[('user tag', 'event time', 'service config name', 'service name'),
                   ('pv name', 'string value', 'double value', 'long value', 'dbr type', 'isConnected',
                    'secondsPastEpoch', 'nanoSeconds', 'timeStampTag', 'alarmSeverity', 'alarmStatus', 'alarmMessage',
                    'is_array', 'array_value')]]
        if eid is not None:
            if isinstance(eid, (str, unicode)):
                eid = int(eid)
            mongoconn, collection = utils.conn(host=os.environ["MASAR_MONGO_HOST"],
                                               port=os.environ["MASAR_MONGO_PORT"],
                                               db=os.environ["MASAR_MONGO_DB"])
            eiddata = pymasar.retrievesnapshot(mongoconn, collection, eid)
            configname = pymasar.retrieveconfig(mongoconn, collection, configidx=eiddata["configidx"])[0]["name"]
            utils.close(mongoconn)
            temp = [(eiddata["comment"], eiddata["created_on"], configname, None), ]
            for d in eiddata["masar_data"]:
                temp.append(tuple(d))
            result.append(temp)
        return result
Exemple #18
0
    def saveSnapshot(self, params):
        """Save event with data.

        :param params: a dictionary to carry query condition with structure like: ::

            [[(channel name,), (string value,),(double value,),(long value,),(dbr type),(is connected),
              (second past epoch,),(nano seconds,),(time stamp tag,),
              (alarm severity,),(alarm status,),(alarm message,),
              (is_array), (array_value)
             ],
             {"configname": , # configuration name which the new data set belongs to
              "comment": [optional], # comment description for this new data set
              "approval": [optional], # approval status, False is not provided
              "username": [optional], # user name who commands this action
             }
            ]

        :returns: list with tuple with header description for each field. Structure like: ::

            [event_id] or [-1] if fault

        :raises: ValueError

        """
        key = ['configname', 'comment', 'approval', 'username']
        config, comment, approval, username = self._parseParams(params[1], key)
        if config is None:
            raise ValueError("Unknown configuration when saving a new snapshot event.")
        if approval is None:
            approval = False
        else:
            approval = bool(json.loads(str(approval).lower()))

        result = NTMultiChannel(params[0])
        dataLen = result.getNumberChannel()
        if dataLen == 0:
            raise RuntimeError("No available snapshot data.")

        # values format: the value is raw data from IOC
        # [(channel name,), (value,), (dbr type), (is connected),
        #  (second past epoch,), (nano seconds,), (time stamp tag,),
        # (alarm severity,), (alarm status,), (alarm message,)]
        pvnames = result.getChannelName()
        values = result.getValue()
        dbrtype = result.getDbrType()
        isconnected = result.getIsConnected()
        severity = result.getSeverity()
        status = result.getStatus()
        message = result.getMessage()
        sec = result.getSecondsPastEpoch()
        nanosec = result.getNanoseconds()
        usertag = result.getUserTag()

        # data format: the data is prepared to save into rdb
        # rawdata format
        # [('channel name', 'string value', 'double value', 'long value', 'dbr type', 'is connected',
        #   'seconds past epoch', 'nano seconds', 'time stamp tag', 'alarm severity', 'alarm status',
        #   'alarm message', 'is_array', 'array_value'),
        #  ...
        # ]
        datas = []

        # get IOC raw data
        for i in range(dataLen):
            tmp = []
            if isinstance(values[i], (list, tuple)):
                tmp = [pvnames[i], "", None, None, dbrtype[i], isconnected[i],
                       sec[i], nanosec[i], usertag[i], severity[i], status[i], message[i],
                       1, values[i]]
            else:
                if dbrtype[i] in self.epicsString:
                     tmp = [pvnames[i], values[i], None, None, dbrtype[i], isconnected[i],
                            sec[i], nanosec[i], usertag[i], severity[i], status[i], message[i],
                            0, None]
                else:
                     tmp = [pvnames[i], str(values[i]), values[i], values[i], dbrtype[i], isconnected[i],
                            sec[i], nanosec[i], usertag[i], severity[i], status[i], message[i],
                            0, None]
            datas.append(tmp)

        # save into database
        try:
            mongoconn, collection = utils.conn(host=os.environ["MASAR_MONGO_HOST"],
                                               port=os.environ["MASAR_MONGO_PORT"],
                                               db=os.environ["MASAR_MONGO_DB"])
            configs = pymasar.retrieveconfig(mongoconn, collection, name=config)
            if len(configs) != 1:
                raise RuntimeError("Cannot find a unique configuration.")

            eid = pymasar.saveevent(mongoconn, collection,
                                    configidx=configs[0]["configidx"],
                                    comment=comment,
                                    approval=approval,
                                    username=username,
                                    masar_data=datas)

            utils.close(mongoconn)
            return [eid, ]
        except:
            # keep the same format with a normal operation
            return [-1]
Exemple #19
0
    def testSaveconfig(self):
        name = "SR_All_20140421"
        params = {
            "desc":
            "SR daily SCR setpoint without IS kick and septum: SR and RF",
            "system": "SR",
            "status": "active",
            "version": 20140421,
        }

        newid = saveconfig(self.conn, self.collection, name, **params)
        new = retrieveconfig(self.conn, self.collection, name=name)
        self.assertEqual(len(new), 1,
                         "Should find only one entry instead of %s" % len(new))
        self.assertEqual(newid, new[0]["_id"],
                         "Expecting id %s but got %s" % (newid, new[0]["_id"]))
        with self.assertRaises(ValueError) as context:
            saveconfig(self.conn, self.collection, name, **params)
        self.assertEqual(context.exception.message,
                         "Configuration (%s) exists already." % name)

        name1 = 'SR-All-20140326'
        params1 = {
            "desc": "SR daily SCR setpoint: SR and IS PS, RF",
            "system": "SR",
            "status": "inactive",
            "version": 20140326,
        }
        newid1 = saveconfig(self.conn, self.collection, name1, **params1)
        new1 = retrieveconfig(self.conn, self.collection, name=name1)
        self.assertEqual(
            len(new1), 1,
            "Should find only one entry instead of %s" % len(new1))
        self.assertEqual(
            newid1, new1[0]["_id"],
            "Expecting id %s but got %s" % (newid1, new1[0]["_id"]))
        self.assertEqual(new1[0]["configidx"] - new[0]["configidx"], 1)

        name2 = 'SR-All-LTB_PS_"SRC_20131206'
        params2 = {
            "desc":
            "LTB power supply setpoints, for saving/comparing/restoring",
            "system": "LTB",
            "status": "active",
            "version": 20131206,
        }
        newid2 = saveconfig(self.conn, self.collection, name2, **params2)
        new2 = retrieveconfig(self.conn, self.collection, name=name2)
        self.assertEqual(
            len(new2), 1,
            "Should find only one entry instead of %s" % len(new2))
        self.assertEqual(
            newid2, new2[0]["_id"],
            "Expecting id %s but got %s" % (newid2, new2[0]["_id"]))
        self.assertEqual(new2[0]["configidx"] - new1[0]["configidx"], 1)

        name3 = 'LTB_BR_BTS_20140421'
        params3 = {
            "desc": "BR SCR PVs with IS kick and septum: LTB, BT, BTS, SR IS",
            "system": "LTB, BR, BTS",
            "status": "active",
            "version": 20140421,
        }
        newid3 = saveconfig(self.conn, self.collection, name3, **params3)
        new3 = retrieveconfig(self.conn, self.collection, name=name3)
        self.assertEqual(
            len(new3), 1,
            "Should find only one entry instead of %s" % len(new3))
        self.assertEqual(
            newid3, new3[0]["_id"],
            "Expecting id %s but got %s" % (newid3, new3[0]["_id"]))
        self.assertEqual(new3[0]["configidx"] - new2[0]["configidx"], 1)

        system4SR = retrieveconfig(self.conn, self.collection, system="SR")
        self.assertEqual(len(system4SR), 2)

        system4more = retrieveconfig(self.conn,
                                     self.collection,
                                     system=params3["system"])
        self.assertEqual(len(system4more), 1)

        system4all = retrieveconfig(self.conn, self.collection, system="*")
        self.assertEqual(len(system4all), 4)

        system4all = retrieveconfig(self.conn, self.collection, system="LTB*")
        self.assertEqual(len(system4all), 2)

        system4all = retrieveconfig(self.conn, self.collection, system="L*B*")
        self.assertEqual(len(system4all), 2)

        system4all = retrieveconfig(self.conn, self.collection, system="L*B,*")
        self.assertEqual(len(system4all), 1)

        system4all = retrieveconfig(self.conn,
                                    self.collection,
                                    system="*S*B,*")
        self.assertEqual(len(system4all), 0)
Exemple #20
0
    def testUpdateconfig(self):
        """"""
        name = "SR_All_20140421"
        params = {
            "desc":
            "SR daily SCR setpoint without IS kick and septum: SR and RF",
            "system": "SR",
            "status": "active",
            "version": 20140421,
        }
        with self.assertRaises(RuntimeError) as context:
            updateconfig(self.conn, self.collection, None)
        self.assertEqual(context.exception.message,
                         "Cannot identify configuration to update.")
        time.sleep(1)
        with self.assertRaises(RuntimeError) as context:
            updateconfig(self.conn, self.collection, name)
        self.assertEqual(context.exception.message,
                         "Wrong Mongo document for %s" % name)

        newid = saveconfig(self.conn, self.collection, name, **params)
        res0 = retrieveconfig(self.conn, self.collection, name)
        self.assertTrue(
            updateconfig(self.conn, self.collection, name, status="inactive"))
        res1 = retrieveconfig(self.conn, self.collection, name)
        self.assertEqual(newid, res0[0]["_id"])
        self.assertEqual(newid, res1[0]["_id"])
        self.assertEqual(res0[0]["status"], "active")
        self.assertEqual(res1[0]["status"], "inactive")
        self.assertEqual(res1[0]["created_on"], res0[0]["created_on"])
        time.sleep(1)  # delay required for below updated_on inequality test
        self.assertTrue(
            updateconfig(self.conn, self.collection, name, status="active"))
        res2 = retrieveconfig(self.conn, self.collection, name)
        self.assertEqual(res2[0]["status"], "active")
        self.assertNotEqual(res1[0]["updated_on"], res2[0]["updated_on"])
        self.assertEqual(res1[0]["created_on"], res2[0]["created_on"])
        self.assertEqual(res1[0]["created_on"], res0[0]["created_on"])
        pvs = [
            "RF{Osc:1}Freq:I", "SR-RF{CFC:D}E:Fb-SP", "SR-RF{CFC:D}Phs:Fb-SP",
            "SR-RF{CFC:D}Tuner:PhaOff-SP", "SR:C01-MG{PS:BT1A}I:Sp1-SP",
            "SR:C01-MG{PS:BT1A}I:Sp2-SP", "SR:C01-MG{PS:CH1B}I:Sp1-SP",
            "SR:C01-MG{PS:CH1B}I:Sp2-SP", "SR:C01-MG{PS:CH2B}I:Sp1-SP",
            "SR:C01-MG{PS:CH2B}I:Sp2-SP", "SR:C01-MG{PS:CL1A}I:Sp1-SP",
            "SR:C01-MG{PS:CL1A}I:Sp2-SP", "SR:C01-MG{PS:CL2A}I:Sp1-SP",
            "SR:C01-MG{PS:CL2A}I:Sp2-SP", "SR:C01-MG{PS:CM1A}I:Sp1-SP",
            "SR:C01-MG{PS:CM1A}I:Sp2-SP", "SR:C01-MG{PS:CM1B}I:Sp1-SP",
            "SR:C01-MG{PS:CM1B}I:Sp2-SP", "SR:C01-MG{PS:QH1B}I:Sp1-SP",
            "SR:C01-MG{PS:QH2B}I:Sp1-SP", "SR:C01-MG{PS:QH3B}I:Sp1-SP",
            "SR:C01-MG{PS:QL1A}I:Sp1-SP", "SR:C01-MG{PS:QL2A}I:Sp1-SP",
            "SR:C01-MG{PS:QL3A}I:Sp1-SP", "SR:C01-MG{PS:QM1A}I:Sp1-SP",
            "SR:C01-MG{PS:QM1B}I:Sp1-SP", "SR:C01-MG{PS:QM2A}I:Sp1-SP",
            "SR:C01-MG{PS:QM2B}I:Sp1-SP", "SR:C01-MG{PS:SH4-P2}I:Sp1-SP",
            "SR:C01-MG{PS:SM1A-P2}I:Sp1-SP", "SR:C01-MG{PS:SQKM1A}I:Sp1-SP",
            "SR:C02-MG{PS:BT1A}I:Sp1-SP", "SR:C02-MG{PS:BT1A}I:Sp2-SP",
            "SR:C02-MG{PS:CH1A}I:Sp1-SP", "SR:C02-MG{PS:CH1A}I:Sp2-SP",
            "SR:C02-MG{PS:CH2A}I:Sp1-SP", "SR:C02-MG{PS:CH2A}I:Sp2-SP",
            "SR:C02-MG{PS:CL1B}I:Sp1-SP", "SR:C02-MG{PS:CL1B}I:Sp2-SP",
            "SR:C02-MG{PS:CL2B}I:Sp1-SP", "SR:C02-MG{PS:CL2B}I:Sp2-SP",
            "SR:C02-MG{PS:CM1A}I:Sp1-SP", "SR:C02-MG{PS:CM1A}I:Sp2-SP",
            "SR:C02-MG{PS:CM1B}I:Sp1-SP", "SR:C02-MG{PS:CM1B}I:Sp2-SP",
            "SR:C02-MG{PS:QH1A}I:Sp1-SP", "SR:C02-MG{PS:QH2A}I:Sp1-SP",
            "SR:C02-MG{PS:QH3A}I:Sp1-SP", "SR:C02-MG{PS:QL1B}I:Sp1-SP",
            "SR:C02-MG{PS:QL2B}I:Sp1-SP", "SR:C02-MG{PS:QL3B}I:Sp1-SP",
            "SR:C02-MG{PS:QM1A}I:Sp1-SP", "SR:C02-MG{PS:QM1B}I:Sp1-SP",
            "SR:C02-MG{PS:QM2A}I:Sp1-SP", "SR:C02-MG{PS:QM2B}I:Sp1-SP",
            "SR:C02-MG{PS:SM1B-P2}I:Sp1-SP", "SR:C02-MG{PS:SM2B-P2}I:Sp1-SP",
            "SR:C02-MG{PS:SQKH1A}I:Sp1-SP", "SR:C03-MG{PS:BT1A}I:Sp1-SP",
            "SR:C03-MG{PS:BT1A}I:Sp2-SP", "SR:C03-MG{PS:CH1B}I:Sp1-SP",
            "SR:C03-MG{PS:CH1B}I:Sp2-SP", "SR:C03-MG{PS:CH2B}I:Sp1-SP",
            "SR:C03-MG{PS:CH2B}I:Sp2-SP", "SR:C03-MG{PS:CL1A}I:Sp1-SP",
            "SR:C03-MG{PS:CL1A}I:Sp2-SP", "SR:C03-MG{PS:CL2A}I:Sp1-SP",
            "SR:C03-MG{PS:CL2A}I:Sp2-SP", "SR:C03-MG{PS:CM1A}I:Sp1-SP",
            "SR:C03-MG{PS:CM1A}I:Sp2-SP", "SR:C03-MG{PS:CM1B}I:Sp1-SP",
            "SR:C03-MG{PS:CM1B}I:Sp2-SP", "SR:C03-MG{PS:D-SP}I:Sp1-SP",
            "SR:C03-MG{PS:QH1B}I:Sp1-SP", "SR:C03-MG{PS:QH2B}I:Sp1-SP",
            "SR:C03-MG{PS:QH3B}I:Sp1-SP", "SR:C03-MG{PS:QL1A}I:Sp1-SP",
            "SR:C03-MG{PS:QL2A}I:Sp1-SP", "SR:C03-MG{PS:QL3A}I:Sp1-SP",
            "SR:C03-MG{PS:QM1A}I:Sp1-SP", "SR:C03-MG{PS:QM1B}I:Sp1-SP",
            "SR:C03-MG{PS:QM2A}I:Sp1-SP", "SR:C03-MG{PS:QM2B}I:Sp1-SP",
            "SR:C03-MG{PS:SL2-P2}I:Sp1-SP", "SR:C03-MG{PS:SL3-P2}I:Sp1-SP",
            "SR:C03-MG{PS:SQKM1A}I:Sp1-SP", "SR:C04-MG{PS:BT1A}I:Sp1-SP",
            "SR:C04-MG{PS:BT1A}I:Sp2-SP", "SR:C04-MG{PS:CH1A}I:Sp1-SP",
            "SR:C04-MG{PS:CH1A}I:Sp2-SP", "SR:C04-MG{PS:CH2A}I:Sp1-SP",
            "SR:C04-MG{PS:CH2A}I:Sp2-SP", "SR:C04-MG{PS:CL1B}I:Sp1-SP",
            "SR:C04-MG{PS:CL1B}I:Sp2-SP", "SR:C04-MG{PS:CL2B}I:Sp1-SP",
            "SR:C04-MG{PS:CL2B}I:Sp2-SP", "SR:C04-MG{PS:CM1A}I:Sp1-SP",
            "SR:C04-MG{PS:CM1A}I:Sp2-SP", "SR:C04-MG{PS:CM1B}I:Sp1-SP",
            "SR:C04-MG{PS:CM1B}I:Sp2-SP", "SR:C04-MG{PS:QH1A}I:Sp1-SP",
            "SR:C04-MG{PS:QH2A}I:Sp1-SP", "SR:C04-MG{PS:QH3A}I:Sp1-SP",
            "SR:C04-MG{PS:QL1B}I:Sp1-SP", "SR:C04-MG{PS:QL2B}I:Sp1-SP",
            "SR:C04-MG{PS:QL3B}I:Sp1-SP", "SR:C04-MG{PS:QM1A}I:Sp1-SP",
            "SR:C04-MG{PS:QM1B}I:Sp1-SP", "SR:C04-MG{PS:QM2A}I:Sp1-SP",
            "SR:C04-MG{PS:QM2B}I:Sp1-SP", "SR:C04-MG{PS:SL1-P2}I:Sp1-SP",
            "SR:C04-MG{PS:SQKH1A}I:Sp1-SP", "SR:C05-MG{PS:BT1A}I:Sp1-SP",
            "SR:C05-MG{PS:BT1A}I:Sp2-SP", "SR:C05-MG{PS:CH1B}I:Sp1-SP",
            "SR:C05-MG{PS:CH1B}I:Sp2-SP", "SR:C05-MG{PS:CH2B}I:Sp1-SP",
            "SR:C05-MG{PS:CH2B}I:Sp2-SP", "SR:C05-MG{PS:CL1A}I:Sp1-SP",
            "SR:C05-MG{PS:CL1A}I:Sp2-SP", "SR:C05-MG{PS:CL2A}I:Sp1-SP",
            "SR:C05-MG{PS:CL2A}I:Sp2-SP", "SR:C05-MG{PS:CM1A}I:Sp1-SP",
            "SR:C05-MG{PS:CM1A}I:Sp2-SP", "SR:C05-MG{PS:CM1B}I:Sp1-SP",
            "SR:C05-MG{PS:CM1B}I:Sp2-SP", "SR:C05-MG{PS:QH1B}I:Sp1-SP",
            "SR:C05-MG{PS:QH2B}I:Sp1-SP", "SR:C05-MG{PS:QH3B}I:Sp1-SP",
            "SR:C05-MG{PS:QL1A}I:Sp1-SP", "SR:C05-MG{PS:QL2A}I:Sp1-SP",
            "SR:C05-MG{PS:QL3A}I:Sp1-SP", "SR:C05-MG{PS:QM1A}I:Sp1-SP",
            "SR:C05-MG{PS:QM1B}I:Sp1-SP", "SR:C05-MG{PS:QM2A}I:Sp1-SP",
            "SR:C05-MG{PS:QM2B}I:Sp1-SP", "SR:C05-MG{PS:SQKM1A}I:Sp1-SP",
            "SR:C06-MG{PS:BT1A}I:Sp1-SP", "SR:C06-MG{PS:BT1A}I:Sp2-SP",
            "SR:C06-MG{PS:CH1A}I:Sp1-SP", "SR:C06-MG{PS:CH1A}I:Sp2-SP",
            "SR:C06-MG{PS:CH2A}I:Sp1-SP", "SR:C06-MG{PS:CH2A}I:Sp2-SP",
            "SR:C06-MG{PS:CL1B}I:Sp1-SP", "SR:C06-MG{PS:CL1B}I:Sp2-SP",
            "SR:C06-MG{PS:CL2B}I:Sp1-SP", "SR:C06-MG{PS:CL2B}I:Sp2-SP",
            "SR:C06-MG{PS:CM1A}I:Sp1-SP", "SR:C06-MG{PS:CM1A}I:Sp2-SP",
            "SR:C06-MG{PS:CM1B}I:Sp1-SP", "SR:C06-MG{PS:CM1B}I:Sp2-SP",
            "SR:C06-MG{PS:QH1A}I:Sp1-SP", "SR:C06-MG{PS:QH2A}I:Sp1-SP",
            "SR:C06-MG{PS:QH3A}I:Sp1-SP", "SR:C06-MG{PS:QL1B}I:Sp1-SP",
            "SR:C06-MG{PS:QL2B}I:Sp1-SP", "SR:C06-MG{PS:QL3B}I:Sp1-SP",
            "SR:C06-MG{PS:QM1A}I:Sp1-SP", "SR:C06-MG{PS:QM1B}I:Sp1-SP",
            "SR:C06-MG{PS:QM2A}I:Sp1-SP", "SR:C06-MG{PS:QM2B}I:Sp1-SP",
            "SR:C06-MG{PS:SH1-P3}I:Sp1-SP", "SR:C06-MG{PS:SH3-P3}I:Sp1-SP",
            "SR:C06-MG{PS:SQKH1A}I:Sp1-SP", "SR:C07-MG{PS:BT1A}I:Sp1-SP",
            "SR:C07-MG{PS:BT1A}I:Sp2-SP", "SR:C07-MG{PS:CH1B}I:Sp1-SP",
            "SR:C07-MG{PS:CH1B}I:Sp2-SP", "SR:C07-MG{PS:CH2B}I:Sp1-SP",
            "SR:C07-MG{PS:CH2B}I:Sp2-SP", "SR:C07-MG{PS:CL1A}I:Sp1-SP",
            "SR:C07-MG{PS:CL1A}I:Sp2-SP", "SR:C07-MG{PS:CL2A}I:Sp1-SP",
            "SR:C07-MG{PS:CL2A}I:Sp2-SP", "SR:C07-MG{PS:CM1A}I:Sp1-SP",
            "SR:C07-MG{PS:CM1A}I:Sp2-SP", "SR:C07-MG{PS:CM1B}I:Sp1-SP",
            "SR:C07-MG{PS:CM1B}I:Sp2-SP", "SR:C07-MG{PS:QH1B}I:Sp1-SP",
            "SR:C07-MG{PS:QH2B}I:Sp1-SP", "SR:C07-MG{PS:QH3B}I:Sp1-SP",
            "SR:C07-MG{PS:QL1A}I:Sp1-SP", "SR:C07-MG{PS:QL2A}I:Sp1-SP",
            "SR:C07-MG{PS:QL3A}I:Sp1-SP", "SR:C07-MG{PS:QM1A}I:Sp1-SP",
            "SR:C07-MG{PS:QM1B}I:Sp1-SP", "SR:C07-MG{PS:QM2A}I:Sp1-SP",
            "SR:C07-MG{PS:QM2B}I:Sp1-SP", "SR:C07-MG{PS:SH4-P3}I:Sp1-SP",
            "SR:C07-MG{PS:SM1A-P3}I:Sp1-SP", "SR:C07-MG{PS:SQKM1A}I:Sp1-SP",
            "SR:C08-MG{PS:BT1A}I:Sp1-SP", "SR:C08-MG{PS:BT1A}I:Sp2-SP",
            "SR:C08-MG{PS:CH1A}I:Sp1-SP", "SR:C08-MG{PS:CH1A}I:Sp2-SP",
            "SR:C08-MG{PS:CH2A}I:Sp1-SP", "SR:C08-MG{PS:CH2A}I:Sp2-SP",
            "SR:C08-MG{PS:CL1B}I:Sp1-SP", "SR:C08-MG{PS:CL1B}I:Sp2-SP",
            "SR:C08-MG{PS:CL2B}I:Sp1-SP", "SR:C08-MG{PS:CL2B}I:Sp2-SP",
            "SR:C08-MG{PS:CM1A}I:Sp1-SP", "SR:C08-MG{PS:CM1A}I:Sp2-SP",
            "SR:C08-MG{PS:CM1B}I:Sp1-SP", "SR:C08-MG{PS:CM1B}I:Sp2-SP",
            "SR:C08-MG{PS:QH1A}I:Sp1-SP", "SR:C08-MG{PS:QH2A}I:Sp1-SP",
            "SR:C08-MG{PS:QH3A}I:Sp1-SP", "SR:C08-MG{PS:QL1B}I:Sp1-SP",
            "SR:C08-MG{PS:QL2B}I:Sp1-SP", "SR:C08-MG{PS:QL3B}I:Sp1-SP",
            "SR:C08-MG{PS:QM1A}I:Sp1-SP", "SR:C08-MG{PS:QM1B}I:Sp1-SP",
            "SR:C08-MG{PS:QM2A}I:Sp1-SP", "SR:C08-MG{PS:QM2B}I:Sp1-SP",
            "SR:C08-MG{PS:SH1-DW08}I:Sp1-SP", "SR:C08-MG{PS:SH3-DW08}I:Sp1-SP",
            "SR:C08-MG{PS:SH4-DW08}I:Sp1-SP", "SR:C08-MG{PS:SM1B-P3}I:Sp1-SP",
            "SR:C08-MG{PS:SM2B-P3}I:Sp1-SP", "SR:C08-MG{PS:SQKH1A}I:Sp1-SP",
            "SR:C09-MG{PS:BT1A}I:Sp1-SP", "SR:C09-MG{PS:BT1A}I:Sp2-SP",
            "SR:C09-MG{PS:CH1B}I:Sp1-SP", "SR:C09-MG{PS:CH1B}I:Sp2-SP",
            "SR:C09-MG{PS:CH2B}I:Sp1-SP", "SR:C09-MG{PS:CH2B}I:Sp2-SP",
            "SR:C09-MG{PS:CL1A}I:Sp1-SP", "SR:C09-MG{PS:CL1A}I:Sp2-SP",
            "SR:C09-MG{PS:CL2A}I:Sp1-SP", "SR:C09-MG{PS:CL2A}I:Sp2-SP",
            "SR:C09-MG{PS:CM1A}I:Sp1-SP", "SR:C09-MG{PS:CM1A}I:Sp2-SP",
            "SR:C09-MG{PS:CM1B}I:Sp1-SP", "SR:C09-MG{PS:CM1B}I:Sp2-SP",
            "SR:C09-MG{PS:QH1B}I:Sp1-SP", "SR:C09-MG{PS:QH2B}I:Sp1-SP",
            "SR:C09-MG{PS:QH3B}I:Sp1-SP", "SR:C09-MG{PS:QL1A}I:Sp1-SP",
            "SR:C09-MG{PS:QL2A}I:Sp1-SP", "SR:C09-MG{PS:QL3A}I:Sp1-SP",
            "SR:C09-MG{PS:QM1A}I:Sp1-SP", "SR:C09-MG{PS:QM1B}I:Sp1-SP",
            "SR:C09-MG{PS:QM2A}I:Sp1-SP", "SR:C09-MG{PS:QM2B}I:Sp1-SP",
            "SR:C09-MG{PS:SL2-P3}I:Sp1-SP", "SR:C09-MG{PS:SL3-P3}I:Sp1-SP",
            "SR:C09-MG{PS:SQKM1A}I:Sp1-SP", "SR:C10-MG{PS:BT1A}I:Sp1-SP",
            "SR:C10-MG{PS:BT1A}I:Sp2-SP", "SR:C10-MG{PS:CH1A}I:Sp1-SP",
            "SR:C10-MG{PS:CH1A}I:Sp2-SP", "SR:C10-MG{PS:CH2A}I:Sp1-SP",
            "SR:C10-MG{PS:CH2A}I:Sp2-SP", "SR:C10-MG{PS:CL1B}I:Sp1-SP",
            "SR:C10-MG{PS:CL1B}I:Sp2-SP", "SR:C10-MG{PS:CL2B}I:Sp1-SP",
            "SR:C10-MG{PS:CL2B}I:Sp2-SP", "SR:C10-MG{PS:CM1A}I:Sp1-SP",
            "SR:C10-MG{PS:CM1A}I:Sp2-SP", "SR:C10-MG{PS:CM1B}I:Sp1-SP",
            "SR:C10-MG{PS:CM1B}I:Sp2-SP", "SR:C10-MG{PS:QH1A}I:Sp1-SP",
            "SR:C10-MG{PS:QH2A}I:Sp1-SP", "SR:C10-MG{PS:QH3A}I:Sp1-SP",
            "SR:C10-MG{PS:QL1B}I:Sp1-SP", "SR:C10-MG{PS:QL2B}I:Sp1-SP",
            "SR:C10-MG{PS:QL3B}I:Sp1-SP", "SR:C10-MG{PS:QM1A}I:Sp1-SP",
            "SR:C10-MG{PS:QM1B}I:Sp1-SP", "SR:C10-MG{PS:QM2A}I:Sp1-SP",
            "SR:C10-MG{PS:QM2B}I:Sp1-SP", "SR:C10-MG{PS:SL1-P3}I:Sp1-SP",
            "SR:C10-MG{PS:SQKH1A}I:Sp1-SP", "SR:C11-MG{PS:BT1A}I:Sp1-SP",
            "SR:C11-MG{PS:BT1A}I:Sp2-SP", "SR:C11-MG{PS:CH1B}I:Sp1-SP",
            "SR:C11-MG{PS:CH1B}I:Sp2-SP", "SR:C11-MG{PS:CH2B}I:Sp1-SP",
            "SR:C11-MG{PS:CH2B}I:Sp2-SP", "SR:C11-MG{PS:CL1A}I:Sp1-SP",
            "SR:C11-MG{PS:CL1A}I:Sp2-SP", "SR:C11-MG{PS:CL2A}I:Sp1-SP",
            "SR:C11-MG{PS:CL2A}I:Sp2-SP", "SR:C11-MG{PS:CM1A}I:Sp1-SP",
            "SR:C11-MG{PS:CM1A}I:Sp2-SP", "SR:C11-MG{PS:CM1B}I:Sp1-SP",
            "SR:C11-MG{PS:CM1B}I:Sp2-SP", "SR:C11-MG{PS:QH1B}I:Sp1-SP",
            "SR:C11-MG{PS:QH2B}I:Sp1-SP", "SR:C11-MG{PS:QH3B}I:Sp1-SP",
            "SR:C11-MG{PS:QL1A}I:Sp1-SP", "SR:C11-MG{PS:QL2A}I:Sp1-SP",
            "SR:C11-MG{PS:QL3A}I:Sp1-SP", "SR:C11-MG{PS:QM1A}I:Sp1-SP",
            "SR:C11-MG{PS:QM1B}I:Sp1-SP", "SR:C11-MG{PS:QM2A}I:Sp1-SP",
            "SR:C11-MG{PS:QM2B}I:Sp1-SP", "SR:C11-MG{PS:SQKM1A}I:Sp1-SP",
            "SR:C12-MG{PS:BT1A}I:Sp1-SP", "SR:C12-MG{PS:BT1A}I:Sp2-SP",
            "SR:C12-MG{PS:CH1A}I:Sp1-SP", "SR:C12-MG{PS:CH1A}I:Sp2-SP",
            "SR:C12-MG{PS:CH2A}I:Sp1-SP", "SR:C12-MG{PS:CH2A}I:Sp2-SP",
            "SR:C12-MG{PS:CL1B}I:Sp1-SP", "SR:C12-MG{PS:CL1B}I:Sp2-SP",
            "SR:C12-MG{PS:CL2B}I:Sp1-SP", "SR:C12-MG{PS:CL2B}I:Sp2-SP",
            "SR:C12-MG{PS:CM1A}I:Sp1-SP", "SR:C12-MG{PS:CM1A}I:Sp2-SP",
            "SR:C12-MG{PS:CM1B}I:Sp1-SP", "SR:C12-MG{PS:CM1B}I:Sp2-SP",
            "SR:C12-MG{PS:QH1A}I:Sp1-SP", "SR:C12-MG{PS:QH2A}I:Sp1-SP",
            "SR:C12-MG{PS:QH3A}I:Sp1-SP", "SR:C12-MG{PS:QL1B}I:Sp1-SP",
            "SR:C12-MG{PS:QL2B}I:Sp1-SP", "SR:C12-MG{PS:QL3B}I:Sp1-SP",
            "SR:C12-MG{PS:QM1A}I:Sp1-SP", "SR:C12-MG{PS:QM1B}I:Sp1-SP",
            "SR:C12-MG{PS:QM2A}I:Sp1-SP", "SR:C12-MG{PS:QM2B}I:Sp1-SP",
            "SR:C12-MG{PS:SH1-P4}I:Sp1-SP", "SR:C12-MG{PS:SH3-P4}I:Sp1-SP",
            "SR:C12-MG{PS:SQKH1A}I:Sp1-SP", "SR:C13-MG{PS:BT1A}I:Sp1-SP",
            "SR:C13-MG{PS:BT1A}I:Sp2-SP", "SR:C13-MG{PS:CH1B}I:Sp1-SP",
            "SR:C13-MG{PS:CH1B}I:Sp2-SP", "SR:C13-MG{PS:CH2B}I:Sp1-SP",
            "SR:C13-MG{PS:CH2B}I:Sp2-SP", "SR:C13-MG{PS:CL1A}I:Sp1-SP",
            "SR:C13-MG{PS:CL1A}I:Sp2-SP", "SR:C13-MG{PS:CL2A}I:Sp1-SP",
            "SR:C13-MG{PS:CL2A}I:Sp2-SP", "SR:C13-MG{PS:CM1A}I:Sp1-SP",
            "SR:C13-MG{PS:CM1A}I:Sp2-SP", "SR:C13-MG{PS:CM1B}I:Sp1-SP",
            "SR:C13-MG{PS:CM1B}I:Sp2-SP", "SR:C13-MG{PS:QH1B}I:Sp1-SP",
            "SR:C13-MG{PS:QH2B}I:Sp1-SP", "SR:C13-MG{PS:QH3B}I:Sp1-SP",
            "SR:C13-MG{PS:QL1A}I:Sp1-SP", "SR:C13-MG{PS:QL2A}I:Sp1-SP",
            "SR:C13-MG{PS:QL3A}I:Sp1-SP", "SR:C13-MG{PS:QM1A}I:Sp1-SP",
            "SR:C13-MG{PS:QM1B}I:Sp1-SP", "SR:C13-MG{PS:QM2A}I:Sp1-SP",
            "SR:C13-MG{PS:QM2B}I:Sp1-SP", "SR:C13-MG{PS:SH4-P4}I:Sp1-SP",
            "SR:C13-MG{PS:SM1A-P4}I:Sp1-SP", "SR:C13-MG{PS:SQKM1A}I:Sp1-SP",
            "SR:C14-MG{PS:BT1A}I:Sp1-SP", "SR:C14-MG{PS:BT1A}I:Sp2-SP",
            "SR:C14-MG{PS:CH1A}I:Sp1-SP", "SR:C14-MG{PS:CH1A}I:Sp2-SP",
            "SR:C14-MG{PS:CH2A}I:Sp1-SP", "SR:C14-MG{PS:CH2A}I:Sp2-SP",
            "SR:C14-MG{PS:CL1B}I:Sp1-SP", "SR:C14-MG{PS:CL1B}I:Sp2-SP",
            "SR:C14-MG{PS:CL2B}I:Sp1-SP", "SR:C14-MG{PS:CL2B}I:Sp2-SP",
            "SR:C14-MG{PS:CM1A}I:Sp1-SP", "SR:C14-MG{PS:CM1A}I:Sp2-SP",
            "SR:C14-MG{PS:CM1B}I:Sp1-SP", "SR:C14-MG{PS:CM1B}I:Sp2-SP",
            "SR:C14-MG{PS:QH1A}I:Sp1-SP", "SR:C14-MG{PS:QH2A}I:Sp1-SP",
            "SR:C14-MG{PS:QH3A}I:Sp1-SP", "SR:C14-MG{PS:QL1B}I:Sp1-SP",
            "SR:C14-MG{PS:QL2B}I:Sp1-SP", "SR:C14-MG{PS:QL3B}I:Sp1-SP",
            "SR:C14-MG{PS:QM1A}I:Sp1-SP", "SR:C14-MG{PS:QM1B}I:Sp1-SP",
            "SR:C14-MG{PS:QM2A}I:Sp1-SP", "SR:C14-MG{PS:QM2B}I:Sp1-SP",
            "SR:C14-MG{PS:SM1B-P4}I:Sp1-SP", "SR:C14-MG{PS:SM2B-P4}I:Sp1-SP",
            "SR:C14-MG{PS:SQKH1A}I:Sp1-SP", "SR:C15-MG{PS:BT1A}I:Sp1-SP",
            "SR:C15-MG{PS:BT1A}I:Sp2-SP", "SR:C15-MG{PS:CH1B}I:Sp1-SP",
            "SR:C15-MG{PS:CH1B}I:Sp2-SP", "SR:C15-MG{PS:CH2B}I:Sp1-SP",
            "SR:C15-MG{PS:CH2B}I:Sp2-SP", "SR:C15-MG{PS:CL1A}I:Sp1-SP",
            "SR:C15-MG{PS:CL1A}I:Sp2-SP", "SR:C15-MG{PS:CL2A}I:Sp1-SP",
            "SR:C15-MG{PS:CL2A}I:Sp2-SP", "SR:C15-MG{PS:CM1A}I:Sp1-SP",
            "SR:C15-MG{PS:CM1A}I:Sp2-SP", "SR:C15-MG{PS:CM1B}I:Sp1-SP",
            "SR:C15-MG{PS:CM1B}I:Sp2-SP", "SR:C15-MG{PS:QH1B}I:Sp1-SP",
            "SR:C15-MG{PS:QH2B}I:Sp1-SP", "SR:C15-MG{PS:QH3B}I:Sp1-SP",
            "SR:C15-MG{PS:QL1A}I:Sp1-SP", "SR:C15-MG{PS:QL2A}I:Sp1-SP",
            "SR:C15-MG{PS:QL3A}I:Sp1-SP", "SR:C15-MG{PS:QM1A}I:Sp1-SP",
            "SR:C15-MG{PS:QM1B}I:Sp1-SP", "SR:C15-MG{PS:QM2A}I:Sp1-SP",
            "SR:C15-MG{PS:QM2B}I:Sp1-SP", "SR:C15-MG{PS:SL2-P4}I:Sp1-SP",
            "SR:C15-MG{PS:SL3-P4}I:Sp1-SP", "SR:C15-MG{PS:SQKM1A}I:Sp1-SP",
            "SR:C16-MG{PS:BT1A}I:Sp1-SP", "SR:C16-MG{PS:BT1A}I:Sp2-SP",
            "SR:C16-MG{PS:CH1A}I:Sp1-SP", "SR:C16-MG{PS:CH1A}I:Sp2-SP",
            "SR:C16-MG{PS:CH2A}I:Sp1-SP", "SR:C16-MG{PS:CH2A}I:Sp2-SP",
            "SR:C16-MG{PS:CL1B}I:Sp1-SP", "SR:C16-MG{PS:CL1B}I:Sp2-SP",
            "SR:C16-MG{PS:CL2B}I:Sp1-SP", "SR:C16-MG{PS:CL2B}I:Sp2-SP",
            "SR:C16-MG{PS:CM1A}I:Sp1-SP", "SR:C16-MG{PS:CM1A}I:Sp2-SP",
            "SR:C16-MG{PS:CM1B}I:Sp1-SP", "SR:C16-MG{PS:CM1B}I:Sp2-SP",
            "SR:C16-MG{PS:QH1A}I:Sp1-SP", "SR:C16-MG{PS:QH2A}I:Sp1-SP",
            "SR:C16-MG{PS:QH3A}I:Sp1-SP", "SR:C16-MG{PS:QL1B}I:Sp1-SP",
            "SR:C16-MG{PS:QL2B}I:Sp1-SP", "SR:C16-MG{PS:QL3B}I:Sp1-SP",
            "SR:C16-MG{PS:QM1A}I:Sp1-SP", "SR:C16-MG{PS:QM1B}I:Sp1-SP",
            "SR:C16-MG{PS:QM2A}I:Sp1-SP", "SR:C16-MG{PS:QM2B}I:Sp1-SP",
            "SR:C16-MG{PS:SL1-P4}I:Sp1-SP", "SR:C16-MG{PS:SQKH1A}I:Sp1-SP",
            "SR:C17-MG{PS:BT1A}I:Sp1-SP", "SR:C17-MG{PS:BT1A}I:Sp2-SP",
            "SR:C17-MG{PS:CH1B}I:Sp1-SP", "SR:C17-MG{PS:CH1B}I:Sp2-SP",
            "SR:C17-MG{PS:CH2B}I:Sp1-SP", "SR:C17-MG{PS:CH2B}I:Sp2-SP",
            "SR:C17-MG{PS:CL1A}I:Sp1-SP", "SR:C17-MG{PS:CL1A}I:Sp2-SP",
            "SR:C17-MG{PS:CL2A}I:Sp1-SP", "SR:C17-MG{PS:CL2A}I:Sp2-SP",
            "SR:C17-MG{PS:CM1A}I:Sp1-SP", "SR:C17-MG{PS:CM1A}I:Sp2-SP",
            "SR:C17-MG{PS:CM1B}I:Sp1-SP", "SR:C17-MG{PS:CM1B}I:Sp2-SP",
            "SR:C17-MG{PS:QH1B}I:Sp1-SP", "SR:C17-MG{PS:QH2B}I:Sp1-SP",
            "SR:C17-MG{PS:QH3B}I:Sp1-SP", "SR:C17-MG{PS:QL1A}I:Sp1-SP",
            "SR:C17-MG{PS:QL2A}I:Sp1-SP", "SR:C17-MG{PS:QL3A}I:Sp1-SP",
            "SR:C17-MG{PS:QM1A}I:Sp1-SP", "SR:C17-MG{PS:QM1B}I:Sp1-SP",
            "SR:C17-MG{PS:QM2A}I:Sp1-SP", "SR:C17-MG{PS:QM2B}I:Sp1-SP",
            "SR:C17-MG{PS:SQKM1A}I:Sp1-SP", "SR:C18-MG{PS:BT1A}I:Sp1-SP",
            "SR:C18-MG{PS:BT1A}I:Sp2-SP", "SR:C18-MG{PS:CH1A}I:Sp1-SP",
            "SR:C18-MG{PS:CH1A}I:Sp2-SP", "SR:C18-MG{PS:CH2A}I:Sp1-SP",
            "SR:C18-MG{PS:CH2A}I:Sp2-SP", "SR:C18-MG{PS:CL1B}I:Sp1-SP",
            "SR:C18-MG{PS:CL1B}I:Sp2-SP", "SR:C18-MG{PS:CL2B}I:Sp1-SP",
            "SR:C18-MG{PS:CL2B}I:Sp2-SP", "SR:C18-MG{PS:CM1A}I:Sp1-SP",
            "SR:C18-MG{PS:CM1A}I:Sp2-SP", "SR:C18-MG{PS:CM1B}I:Sp1-SP",
            "SR:C18-MG{PS:CM1B}I:Sp2-SP", "SR:C18-MG{PS:QH1A}I:Sp1-SP",
            "SR:C18-MG{PS:QH2A}I:Sp1-SP", "SR:C18-MG{PS:QH3A}I:Sp1-SP",
            "SR:C18-MG{PS:QL1B}I:Sp1-SP", "SR:C18-MG{PS:QL2B}I:Sp1-SP",
            "SR:C18-MG{PS:QL3B}I:Sp1-SP", "SR:C18-MG{PS:QM1A}I:Sp1-SP",
            "SR:C18-MG{PS:QM1B}I:Sp1-SP", "SR:C18-MG{PS:QM2A}I:Sp1-SP",
            "SR:C18-MG{PS:QM2B}I:Sp1-SP", "SR:C18-MG{PS:SH1-DW18}I:Sp1-SP",
            "SR:C18-MG{PS:SH1-P5}I:Sp1-SP", "SR:C18-MG{PS:SH3-DW18}I:Sp1-SP",
            "SR:C18-MG{PS:SH3-P5}I:Sp1-SP", "SR:C18-MG{PS:SH4-DW18}I:Sp1-SP",
            "SR:C18-MG{PS:SQKH1A}I:Sp1-SP", "SR:C19-MG{PS:BT1A}I:Sp1-SP",
            "SR:C19-MG{PS:BT1A}I:Sp2-SP", "SR:C19-MG{PS:CH1B}I:Sp1-SP",
            "SR:C19-MG{PS:CH1B}I:Sp2-SP", "SR:C19-MG{PS:CH2B}I:Sp1-SP",
            "SR:C19-MG{PS:CH2B}I:Sp2-SP", "SR:C19-MG{PS:CL1A}I:Sp1-SP",
            "SR:C19-MG{PS:CL1A}I:Sp2-SP", "SR:C19-MG{PS:CL2A}I:Sp1-SP",
            "SR:C19-MG{PS:CL2A}I:Sp2-SP", "SR:C19-MG{PS:CM1A}I:Sp1-SP",
            "SR:C19-MG{PS:CM1A}I:Sp2-SP", "SR:C19-MG{PS:CM1B}I:Sp1-SP",
            "SR:C19-MG{PS:CM1B}I:Sp2-SP", "SR:C19-MG{PS:QH1B}I:Sp1-SP",
            "SR:C19-MG{PS:QH2B}I:Sp1-SP", "SR:C19-MG{PS:QH3B}I:Sp1-SP",
            "SR:C19-MG{PS:QL1A}I:Sp1-SP", "SR:C19-MG{PS:QL2A}I:Sp1-SP",
            "SR:C19-MG{PS:QL3A}I:Sp1-SP", "SR:C19-MG{PS:QM1A}I:Sp1-SP",
            "SR:C19-MG{PS:QM1B}I:Sp1-SP", "SR:C19-MG{PS:QM2A}I:Sp1-SP",
            "SR:C19-MG{PS:QM2B}I:Sp1-SP", "SR:C19-MG{PS:SH4-P5}I:Sp1-SP",
            "SR:C19-MG{PS:SM1A-P5}I:Sp1-SP", "SR:C19-MG{PS:SQKM1A}I:Sp1-SP",
            "SR:C20-MG{PS:BT1A}I:Sp1-SP", "SR:C20-MG{PS:BT1A}I:Sp2-SP",
            "SR:C20-MG{PS:CH1A}I:Sp1-SP", "SR:C20-MG{PS:CH1A}I:Sp2-SP",
            "SR:C20-MG{PS:CH2A}I:Sp1-SP", "SR:C20-MG{PS:CH2A}I:Sp2-SP",
            "SR:C20-MG{PS:CL1B}I:Sp1-SP", "SR:C20-MG{PS:CL1B}I:Sp2-SP",
            "SR:C20-MG{PS:CL2B}I:Sp1-SP", "SR:C20-MG{PS:CL2B}I:Sp2-SP",
            "SR:C20-MG{PS:CM1A}I:Sp1-SP", "SR:C20-MG{PS:CM1A}I:Sp2-SP",
            "SR:C20-MG{PS:CM1B}I:Sp1-SP", "SR:C20-MG{PS:CM1B}I:Sp2-SP",
            "SR:C20-MG{PS:QH1A}I:Sp1-SP", "SR:C20-MG{PS:QH2A}I:Sp1-SP",
            "SR:C20-MG{PS:QH3A}I:Sp1-SP", "SR:C20-MG{PS:QL1B}I:Sp1-SP",
            "SR:C20-MG{PS:QL2B}I:Sp1-SP", "SR:C20-MG{PS:QL3B}I:Sp1-SP",
            "SR:C20-MG{PS:QM1A}I:Sp1-SP", "SR:C20-MG{PS:QM1B}I:Sp1-SP",
            "SR:C20-MG{PS:QM2A}I:Sp1-SP", "SR:C20-MG{PS:QM2B}I:Sp1-SP",
            "SR:C20-MG{PS:SM1B-P5}I:Sp1-SP", "SR:C20-MG{PS:SM2B-P5}I:Sp1-SP",
            "SR:C20-MG{PS:SQKH1A}I:Sp1-SP", "SR:C21-MG{PS:BT1A}I:Sp1-SP",
            "SR:C21-MG{PS:BT1A}I:Sp2-SP", "SR:C21-MG{PS:CH1B}I:Sp1-SP",
            "SR:C21-MG{PS:CH1B}I:Sp2-SP", "SR:C21-MG{PS:CH2B}I:Sp1-SP",
            "SR:C21-MG{PS:CH2B}I:Sp2-SP", "SR:C21-MG{PS:CL1A}I:Sp1-SP",
            "SR:C21-MG{PS:CL1A}I:Sp2-SP", "SR:C21-MG{PS:CL2A}I:Sp1-SP",
            "SR:C21-MG{PS:CL2A}I:Sp2-SP", "SR:C21-MG{PS:CM1A}I:Sp1-SP",
            "SR:C21-MG{PS:CM1A}I:Sp2-SP", "SR:C21-MG{PS:CM1B}I:Sp1-SP",
            "SR:C21-MG{PS:CM1B}I:Sp2-SP", "SR:C21-MG{PS:QH1B}I:Sp1-SP",
            "SR:C21-MG{PS:QH2B}I:Sp1-SP", "SR:C21-MG{PS:QH3B}I:Sp1-SP",
            "SR:C21-MG{PS:QL1A}I:Sp1-SP", "SR:C21-MG{PS:QL2A}I:Sp1-SP",
            "SR:C21-MG{PS:QL3A}I:Sp1-SP", "SR:C21-MG{PS:QM1A}I:Sp1-SP",
            "SR:C21-MG{PS:QM1B}I:Sp1-SP", "SR:C21-MG{PS:QM2A}I:Sp1-SP",
            "SR:C21-MG{PS:QM2B}I:Sp1-SP", "SR:C21-MG{PS:SL2-P5}I:Sp1-SP",
            "SR:C21-MG{PS:SL3-P5}I:Sp1-SP", "SR:C21-MG{PS:SQKM1A}I:Sp1-SP",
            "SR:C22-MG{PS:BT1A}I:Sp1-SP", "SR:C22-MG{PS:BT1A}I:Sp2-SP",
            "SR:C22-MG{PS:CH1A}I:Sp1-SP", "SR:C22-MG{PS:CH1A}I:Sp2-SP",
            "SR:C22-MG{PS:CH2A}I:Sp1-SP", "SR:C22-MG{PS:CH2A}I:Sp2-SP",
            "SR:C22-MG{PS:CL1B}I:Sp1-SP", "SR:C22-MG{PS:CL1B}I:Sp2-SP",
            "SR:C22-MG{PS:CL2B}I:Sp1-SP", "SR:C22-MG{PS:CL2B}I:Sp2-SP",
            "SR:C22-MG{PS:CM1A}I:Sp1-SP", "SR:C22-MG{PS:CM1A}I:Sp2-SP",
            "SR:C22-MG{PS:CM1B}I:Sp1-SP", "SR:C22-MG{PS:CM1B}I:Sp2-SP",
            "SR:C22-MG{PS:QH1A}I:Sp1-SP", "SR:C22-MG{PS:QH2A}I:Sp1-SP",
            "SR:C22-MG{PS:QH3A}I:Sp1-SP", "SR:C22-MG{PS:QL1B}I:Sp1-SP",
            "SR:C22-MG{PS:QL2B}I:Sp1-SP", "SR:C22-MG{PS:QL3B}I:Sp1-SP",
            "SR:C22-MG{PS:QM1A}I:Sp1-SP", "SR:C22-MG{PS:QM1B}I:Sp1-SP",
            "SR:C22-MG{PS:QM2A}I:Sp1-SP", "SR:C22-MG{PS:QM2B}I:Sp1-SP",
            "SR:C22-MG{PS:SL1-P5}I:Sp1-SP", "SR:C22-MG{PS:SQKH1A}I:Sp1-SP",
            "SR:C23-MG{PS:BT1A}I:Sp1-SP", "SR:C23-MG{PS:BT1A}I:Sp2-SP",
            "SR:C23-MG{PS:CH1B}I:Sp1-SP", "SR:C23-MG{PS:CH1B}I:Sp2-SP",
            "SR:C23-MG{PS:CH2B}I:Sp1-SP", "SR:C23-MG{PS:CH2B}I:Sp2-SP",
            "SR:C23-MG{PS:CL1A}I:Sp1-SP", "SR:C23-MG{PS:CL1A}I:Sp2-SP",
            "SR:C23-MG{PS:CL2A}I:Sp1-SP", "SR:C23-MG{PS:CL2A}I:Sp2-SP",
            "SR:C23-MG{PS:CM1A}I:Sp1-SP", "SR:C23-MG{PS:CM1A}I:Sp2-SP",
            "SR:C23-MG{PS:CM1B}I:Sp1-SP", "SR:C23-MG{PS:CM1B}I:Sp2-SP",
            "SR:C23-MG{PS:QH1B}I:Sp1-SP", "SR:C23-MG{PS:QH2B}I:Sp1-SP",
            "SR:C23-MG{PS:QH3B}I:Sp1-SP", "SR:C23-MG{PS:QL1A}I:Sp1-SP",
            "SR:C23-MG{PS:QL2A}I:Sp1-SP", "SR:C23-MG{PS:QL3A}I:Sp1-SP",
            "SR:C23-MG{PS:QM1A}I:Sp1-SP", "SR:C23-MG{PS:QM1B}I:Sp1-SP",
            "SR:C23-MG{PS:QM2A}I:Sp1-SP", "SR:C23-MG{PS:QM2B}I:Sp1-SP",
            "SR:C23-MG{PS:SQKM1A}I:Sp1-SP", "SR:C24-MG{PS:BT1A}I:Sp1-SP",
            "SR:C24-MG{PS:BT1A}I:Sp2-SP", "SR:C24-MG{PS:CH1A}I:Sp1-SP",
            "SR:C24-MG{PS:CH1A}I:Sp2-SP", "SR:C24-MG{PS:CH2A}I:Sp1-SP",
            "SR:C24-MG{PS:CH2A}I:Sp2-SP", "SR:C24-MG{PS:CL1B}I:Sp1-SP",
            "SR:C24-MG{PS:CL1B}I:Sp2-SP", "SR:C24-MG{PS:CL2B}I:Sp1-SP",
            "SR:C24-MG{PS:CL2B}I:Sp2-SP", "SR:C24-MG{PS:CM1A}I:Sp1-SP",
            "SR:C24-MG{PS:CM1A}I:Sp2-SP", "SR:C24-MG{PS:CM1B}I:Sp1-SP",
            "SR:C24-MG{PS:CM1B}I:Sp2-SP", "SR:C24-MG{PS:QH1A}I:Sp1-SP",
            "SR:C24-MG{PS:QH2A}I:Sp1-SP", "SR:C24-MG{PS:QH3A}I:Sp1-SP",
            "SR:C24-MG{PS:QL1B}I:Sp1-SP", "SR:C24-MG{PS:QL2B}I:Sp1-SP",
            "SR:C24-MG{PS:QL3B}I:Sp1-SP", "SR:C24-MG{PS:QM1A}I:Sp1-SP",
            "SR:C24-MG{PS:QM1B}I:Sp1-SP", "SR:C24-MG{PS:QM2A}I:Sp1-SP",
            "SR:C24-MG{PS:QM2B}I:Sp1-SP", "SR:C24-MG{PS:SH1-P1}I:Sp1-SP",
            "SR:C24-MG{PS:SH3-P1}I:Sp1-SP", "SR:C24-MG{PS:SQKH1A}I:Sp1-SP",
            "SR:C25-MG{PS:BT1A}I:Sp1-SP", "SR:C25-MG{PS:BT1A}I:Sp2-SP",
            "SR:C25-MG{PS:CH1B}I:Sp1-SP", "SR:C25-MG{PS:CH1B}I:Sp2-SP",
            "SR:C25-MG{PS:CH2B}I:Sp1-SP", "SR:C25-MG{PS:CH2B}I:Sp2-SP",
            "SR:C25-MG{PS:CL1A}I:Sp1-SP", "SR:C25-MG{PS:CL1A}I:Sp2-SP",
            "SR:C25-MG{PS:CL2A}I:Sp1-SP", "SR:C25-MG{PS:CL2A}I:Sp2-SP",
            "SR:C25-MG{PS:CM1A}I:Sp1-SP", "SR:C25-MG{PS:CM1A}I:Sp2-SP",
            "SR:C25-MG{PS:CM1B}I:Sp1-SP", "SR:C25-MG{PS:CM1B}I:Sp2-SP",
            "SR:C25-MG{PS:QH1B}I:Sp1-SP", "SR:C25-MG{PS:QH2B}I:Sp1-SP",
            "SR:C25-MG{PS:QH3B}I:Sp1-SP", "SR:C25-MG{PS:QL1A}I:Sp1-SP",
            "SR:C25-MG{PS:QL2A}I:Sp1-SP", "SR:C25-MG{PS:QL3A}I:Sp1-SP",
            "SR:C25-MG{PS:QM1A}I:Sp1-SP", "SR:C25-MG{PS:QM1B}I:Sp1-SP",
            "SR:C25-MG{PS:QM2A}I:Sp1-SP", "SR:C25-MG{PS:QM2B}I:Sp1-SP",
            "SR:C25-MG{PS:SH4-P1}I:Sp1-SP", "SR:C25-MG{PS:SM1A-P1}I:Sp1-SP",
            "SR:C25-MG{PS:SQKM1A}I:Sp1-SP", "SR:C26-MG{PS:BT1A}I:Sp1-SP",
            "SR:C26-MG{PS:BT1A}I:Sp2-SP", "SR:C26-MG{PS:CH1A}I:Sp1-SP",
            "SR:C26-MG{PS:CH1A}I:Sp2-SP", "SR:C26-MG{PS:CH2A}I:Sp1-SP",
            "SR:C26-MG{PS:CH2A}I:Sp2-SP", "SR:C26-MG{PS:CL1B}I:Sp1-SP",
            "SR:C26-MG{PS:CL1B}I:Sp2-SP", "SR:C26-MG{PS:CL2B}I:Sp1-SP",
            "SR:C26-MG{PS:CL2B}I:Sp2-SP", "SR:C26-MG{PS:CM1A}I:Sp1-SP",
            "SR:C26-MG{PS:CM1A}I:Sp2-SP", "SR:C26-MG{PS:CM1B}I:Sp1-SP",
            "SR:C26-MG{PS:CM1B}I:Sp2-SP", "SR:C26-MG{PS:QH1A}I:Sp1-SP",
            "SR:C26-MG{PS:QH2A}I:Sp1-SP", "SR:C26-MG{PS:QH3A}I:Sp1-SP",
            "SR:C26-MG{PS:QL1B}I:Sp1-SP", "SR:C26-MG{PS:QL2B}I:Sp1-SP",
            "SR:C26-MG{PS:QL3B}I:Sp1-SP", "SR:C26-MG{PS:QM1A}I:Sp1-SP",
            "SR:C26-MG{PS:QM1B}I:Sp1-SP", "SR:C26-MG{PS:QM2A}I:Sp1-SP",
            "SR:C26-MG{PS:QM2B}I:Sp1-SP", "SR:C26-MG{PS:SM1B-P1}I:Sp1-SP",
            "SR:C26-MG{PS:SM2B-P1}I:Sp1-SP", "SR:C26-MG{PS:SQKH1A}I:Sp1-SP",
            "SR:C27-MG{PS:BT1A}I:Sp1-SP", "SR:C27-MG{PS:BT1A}I:Sp2-SP",
            "SR:C27-MG{PS:CH1B}I:Sp1-SP", "SR:C27-MG{PS:CH1B}I:Sp2-SP",
            "SR:C27-MG{PS:CH2B}I:Sp1-SP", "SR:C27-MG{PS:CH2B}I:Sp2-SP",
            "SR:C27-MG{PS:CL1A}I:Sp1-SP", "SR:C27-MG{PS:CL1A}I:Sp2-SP",
            "SR:C27-MG{PS:CL2A}I:Sp1-SP", "SR:C27-MG{PS:CL2A}I:Sp2-SP",
            "SR:C27-MG{PS:CM1A}I:Sp1-SP", "SR:C27-MG{PS:CM1A}I:Sp2-SP",
            "SR:C27-MG{PS:CM1B}I:Sp1-SP", "SR:C27-MG{PS:CM1B}I:Sp2-SP",
            "SR:C27-MG{PS:QH1B}I:Sp1-SP", "SR:C27-MG{PS:QH2B}I:Sp1-SP",
            "SR:C27-MG{PS:QH3B}I:Sp1-SP", "SR:C27-MG{PS:QL1A}I:Sp1-SP",
            "SR:C27-MG{PS:QL2A}I:Sp1-SP", "SR:C27-MG{PS:QL3A}I:Sp1-SP",
            "SR:C27-MG{PS:QM1A}I:Sp1-SP", "SR:C27-MG{PS:QM1B}I:Sp1-SP",
            "SR:C27-MG{PS:QM2A}I:Sp1-SP", "SR:C27-MG{PS:QM2B}I:Sp1-SP",
            "SR:C27-MG{PS:SL2-P1}I:Sp1-SP", "SR:C27-MG{PS:SL3-P1}I:Sp1-SP",
            "SR:C27-MG{PS:SQKM1A}I:Sp1-SP", "SR:C28-MG{PS:BT1A}I:Sp1-SP",
            "SR:C28-MG{PS:BT1A}I:Sp2-SP", "SR:C28-MG{PS:CH1A}I:Sp1-SP",
            "SR:C28-MG{PS:CH1A}I:Sp2-SP", "SR:C28-MG{PS:CH2A}I:Sp1-SP",
            "SR:C28-MG{PS:CH2A}I:Sp2-SP", "SR:C28-MG{PS:CL1B}I:Sp1-SP",
            "SR:C28-MG{PS:CL1B}I:Sp2-SP", "SR:C28-MG{PS:CL2B}I:Sp1-SP",
            "SR:C28-MG{PS:CL2B}I:Sp2-SP", "SR:C28-MG{PS:CM1A}I:Sp1-SP",
            "SR:C28-MG{PS:CM1A}I:Sp2-SP", "SR:C28-MG{PS:CM1B}I:Sp1-SP",
            "SR:C28-MG{PS:CM1B}I:Sp2-SP", "SR:C28-MG{PS:QH1A}I:Sp1-SP",
            "SR:C28-MG{PS:QH2A}I:Sp1-SP", "SR:C28-MG{PS:QH3A}I:Sp1-SP",
            "SR:C28-MG{PS:QL1B}I:Sp1-SP", "SR:C28-MG{PS:QL2B}I:Sp1-SP",
            "SR:C28-MG{PS:QL3B}I:Sp1-SP", "SR:C28-MG{PS:QM1A}I:Sp1-SP",
            "SR:C28-MG{PS:QM1B}I:Sp1-SP", "SR:C28-MG{PS:QM2A}I:Sp1-SP",
            "SR:C28-MG{PS:QM2B}I:Sp1-SP", "SR:C28-MG{PS:SH1-DW28}I:Sp1-SP",
            "SR:C28-MG{PS:SH3-DW28}I:Sp1-SP", "SR:C28-MG{PS:SH4-DW28}I:Sp1-SP",
            "SR:C28-MG{PS:SL1-P1}I:Sp1-SP", "SR:C28-MG{PS:SQKH1A}I:Sp1-SP",
            "SR:C29-MG{PS:BT1A}I:Sp1-SP", "SR:C29-MG{PS:BT1A}I:Sp2-SP",
            "SR:C29-MG{PS:CH1B}I:Sp1-SP", "SR:C29-MG{PS:CH1B}I:Sp2-SP",
            "SR:C29-MG{PS:CH2B}I:Sp1-SP", "SR:C29-MG{PS:CH2B}I:Sp2-SP",
            "SR:C29-MG{PS:CL1A}I:Sp1-SP", "SR:C29-MG{PS:CL1A}I:Sp2-SP",
            "SR:C29-MG{PS:CL2A}I:Sp1-SP", "SR:C29-MG{PS:CL2A}I:Sp2-SP",
            "SR:C29-MG{PS:CM1A}I:Sp1-SP", "SR:C29-MG{PS:CM1A}I:Sp2-SP",
            "SR:C29-MG{PS:CM1B}I:Sp1-SP", "SR:C29-MG{PS:CM1B}I:Sp2-SP",
            "SR:C29-MG{PS:QH1B}I:Sp1-SP", "SR:C29-MG{PS:QH2B}I:Sp1-SP",
            "SR:C29-MG{PS:QH3B}I:Sp1-SP", "SR:C29-MG{PS:QL1A}I:Sp1-SP",
            "SR:C29-MG{PS:QL2A}I:Sp1-SP", "SR:C29-MG{PS:QL3A}I:Sp1-SP",
            "SR:C29-MG{PS:QM1A}I:Sp1-SP", "SR:C29-MG{PS:QM1B}I:Sp1-SP",
            "SR:C29-MG{PS:QM2A}I:Sp1-SP", "SR:C29-MG{PS:QM2B}I:Sp1-SP",
            "SR:C29-MG{PS:SQKM1A}I:Sp1-SP", "SR:C30-MG{PS:BT1A}I:Sp1-SP",
            "SR:C30-MG{PS:BT1A}I:Sp2-SP", "SR:C30-MG{PS:CH1A}I:Sp1-SP",
            "SR:C30-MG{PS:CH1A}I:Sp2-SP", "SR:C30-MG{PS:CH2A}I:Sp1-SP",
            "SR:C30-MG{PS:CH2A}I:Sp2-SP", "SR:C30-MG{PS:CL1B}I:Sp1-SP",
            "SR:C30-MG{PS:CL1B}I:Sp2-SP", "SR:C30-MG{PS:CL2B}I:Sp1-SP",
            "SR:C30-MG{PS:CL2B}I:Sp2-SP", "SR:C30-MG{PS:CM1A}I:Sp1-SP",
            "SR:C30-MG{PS:CM1A}I:Sp2-SP", "SR:C30-MG{PS:CM1B}I:Sp1-SP",
            "SR:C30-MG{PS:CM1B}I:Sp2-SP", "SR:C30-MG{PS:QH1A}I:Sp1-SP",
            "SR:C30-MG{PS:QH2A}I:Sp1-SP", "SR:C30-MG{PS:QH3A}I:Sp1-SP",
            "SR:C30-MG{PS:QL1B}I:Sp1-SP", "SR:C30-MG{PS:QL2B}I:Sp1-SP",
            "SR:C30-MG{PS:QL3B}I:Sp1-SP", "SR:C30-MG{PS:QM1A}I:Sp1-SP",
            "SR:C30-MG{PS:QM1B}I:Sp1-SP", "SR:C30-MG{PS:QM2A}I:Sp1-SP",
            "SR:C30-MG{PS:QM2B}I:Sp1-SP", "SR:C30-MG{PS:SH1-P2}I:Sp1-SP",
            "SR:C30-MG{PS:SH3-P2}I:Sp1-SP", "SR:C30-MG{PS:SQKH1A}I:Sp1-SP"
        ]
        pvs0 = [
            'SR:C01-MG{PS:SM1A-P2}I:Sp1-SP', 'SR:C02-MG{PS:SM1B-P2}I:Sp1-SP',
            'SR:C02-MG{PS:SM2B-P2}I:Sp1-SP', 'SR:C07-MG{PS:SM1A-P3}I:Sp1-SP',
            'SR:C08-MG{PS:SM1B-P3}I:Sp1-SP', 'SR:C08-MG{PS:SM2B-P3}I:Sp1-SP',
            'SR:C13-MG{PS:SM1A-P4}I:Sp1-SP', 'SR:C14-MG{PS:SM1B-P4}I:Sp1-SP',
            'SR:C14-MG{PS:SM2B-P4}I:Sp1-SP', 'SR:C19-MG{PS:SM1A-P5}I:Sp1-SP',
            'SR:C20-MG{PS:SM1B-P5}I:Sp1-SP', 'SR:C20-MG{PS:SM2B-P5}I:Sp1-SP',
            'SR:C25-MG{PS:SM1A-P1}I:Sp1-SP', 'SR:C26-MG{PS:SM1B-P1}I:Sp1-SP',
            'SR:C26-MG{PS:SM2B-P1}I:Sp1-SP'
        ]

        with self.assertRaises(KeyError) as context:
            updateconfig(self.conn,
                         self.collection,
                         name,
                         pvlist={"name": pvs0})
        self.assertEqual(context.exception.message,
                         'Cannot find key ("names") for pv names.')

        self.assertTrue(
            updateconfig(self.conn,
                         self.collection,
                         name,
                         pvlist={"names": pvs}))
        res3 = retrieveconfig(self.conn, self.collection, name, withpvs=True)
        self.assertEqual(res3[0]["status"], "active")
        self.assertNotEqual(res1[0]["updated_on"], res2[0]["updated_on"])
        self.assertEqual(res3[0]["created_on"], res0[0]["created_on"])
        self.assertEqual(res3[0]["pvlist"]["names"], pvs)
        with self.assertRaises(RuntimeError) as context:
            updateconfig(self.conn,
                         self.collection,
                         name,
                         pvlist={"names": pvs0})
        self.assertEqual(
            context.exception.message,
            "PV collection list exists already, and should not be changed.")
Exemple #21
0
 def testRetrieveconfig(self):
     """"""
     res = retrieveconfig(self.conn, self.collection, "*", "*")
     self.assertEqual(len(res), 0,
                      "Should find zero results from an empty database")
 def testRetrieveconfig(self):
     """"""
     res = retrieveconfig(self.conn, self.collection, "*", "*")
     self.assertEqual(len(res), 0,
                      "Should find zero results from an empty database")
    def testSaveconfig(self):
        name = "SR_All_20140421"
        params = {"desc": "SR daily SCR setpoint without IS kick and septum: SR and RF",
                  "system": "SR",
                  "status": "active",
                  "version": 20140421,
                  }
        
        newid = saveconfig(self.conn, self.collection, name, **params)
        new = retrieveconfig(self.conn, self.collection, name=name)
        self.assertEqual(len(new), 1, 
                         "Should find only one entry instead of %s"%len(new))
        self.assertEqual(newid, new[0]["_id"], 
                         "Expecting id %s but got %s"%(newid, new[0]["_id"]))
        with self.assertRaises(ValueError) as context:
            saveconfig(self.conn, self.collection, name, **params)
        self.assertEqual(context.exception.message, "Configuration (%s) exists already."%name)

        name1 = 'SR-All-20140326'
        params1 = {"desc": "SR daily SCR setpoint: SR and IS PS, RF",
                  "system": "SR",
                  "status": "inactive",
                  "version": 20140326,
                  }
        newid1 = saveconfig(self.conn, self.collection, name1, **params1)
        new1 = retrieveconfig(self.conn, self.collection, name=name1)
        self.assertEqual(len(new1), 1, 
                         "Should find only one entry instead of %s"%len(new1))
        self.assertEqual(newid1, new1[0]["_id"], 
                         "Expecting id %s but got %s"%(newid1, new1[0]["_id"]))
        self.assertEqual(new1[0]["configidx"]-new[0]["configidx"], 1)
        
        name2 = 'SR-All-LTB_PS_"SRC_20131206'
        params2 = {"desc": "LTB power supply setpoints, for saving/comparing/restoring",
                  "system": "LTB",
                  "status": "active",
                  "version": 20131206,
                  }
        newid2 = saveconfig(self.conn, self.collection, name2, **params2)
        new2 = retrieveconfig(self.conn, self.collection, name=name2)
        self.assertEqual(len(new2), 1, 
                         "Should find only one entry instead of %s"%len(new2))
        self.assertEqual(newid2, new2[0]["_id"], 
                         "Expecting id %s but got %s"%(newid2, new2[0]["_id"]))
        self.assertEqual(new2[0]["configidx"]-new1[0]["configidx"], 1)
        
        name3 = 'LTB_BR_BTS_20140421'
        params3 = {"desc": "BR SCR PVs with IS kick and septum: LTB, BT, BTS, SR IS",
                  "system": "LTB, BR, BTS",
                  "status": "active",
                  "version": 20140421,
                  }
        newid3 = saveconfig(self.conn, self.collection, name3, **params3)
        new3 = retrieveconfig(self.conn, self.collection, name=name3)
        self.assertEqual(len(new3), 1, 
                         "Should find only one entry instead of %s"%len(new3))
        self.assertEqual(newid3, new3[0]["_id"], 
                         "Expecting id %s but got %s"%(newid3, new3[0]["_id"]))
        self.assertEqual(new3[0]["configidx"]-new2[0]["configidx"], 1)

        system4SR = retrieveconfig(self.conn, self.collection, system="SR")
        self.assertEqual(len(system4SR), 2)

        system4more = retrieveconfig(self.conn, self.collection, system=params3["system"])
        self.assertEqual(len(system4more), 1)
        
        system4all = retrieveconfig(self.conn, self.collection, system="*")
        self.assertEqual(len(system4all), 4)

        system4all = retrieveconfig(self.conn, self.collection, system="LTB*")
        self.assertEqual(len(system4all), 2)

        system4all = retrieveconfig(self.conn, self.collection, system="L*B*")
        self.assertEqual(len(system4all), 2)

        system4all = retrieveconfig(self.conn, self.collection, system="L*B,*")
        self.assertEqual(len(system4all), 1)

        system4all = retrieveconfig(self.conn, self.collection, system="*S*B,*")
        self.assertEqual(len(system4all), 0)
    def testUpdateconfig(self):
        """"""
        name = "SR_All_20140421"
        params = {"desc": "SR daily SCR setpoint without IS kick and septum: SR and RF",
                  "system": "SR",
                  "status": "active",
                  "version": 20140421,
                  }
        with self.assertRaises(RuntimeError) as context:
            updateconfig(self.conn, self.collection, None)
        self.assertEqual(context.exception.message, "Cannot identify configuration to update.")
        time.sleep(1)
        with self.assertRaises(RuntimeError) as context:
            updateconfig(self.conn, self.collection, name)
        self.assertEqual(context.exception.message, "Wrong Mongo document for %s" % name)

        newid = saveconfig(self.conn, self.collection, name, **params)
        res0 = retrieveconfig(self.conn, self.collection, name)
        self.assertTrue(updateconfig(self.conn, self.collection, name, status="inactive"))
        res1 = retrieveconfig(self.conn, self.collection, name)
        self.assertEqual(newid, res0[0]["_id"])
        self.assertEqual(newid, res1[0]["_id"])
        self.assertEqual(res0[0]["status"], "active")
        self.assertEqual(res1[0]["status"], "inactive")
        self.assertEqual(res1[0]["created_on"], res0[0]["created_on"])
        time.sleep(1)  # delay required for below updated_on inequality test
        self.assertTrue(updateconfig(self.conn, self.collection, name, status="active"))
        res2 = retrieveconfig(self.conn, self.collection, name)
        self.assertEqual(res2[0]["status"], "active")
        self.assertNotEqual(res1[0]["updated_on"], res2[0]["updated_on"])
        self.assertEqual(res1[0]["created_on"], res2[0]["created_on"])
        self.assertEqual(res1[0]["created_on"], res0[0]["created_on"])
        pvs = ["RF{Osc:1}Freq:I",  "SR-RF{CFC:D}E:Fb-SP",  "SR-RF{CFC:D}Phs:Fb-SP",  "SR-RF{CFC:D}Tuner:PhaOff-SP",
               "SR:C01-MG{PS:BT1A}I:Sp1-SP",  "SR:C01-MG{PS:BT1A}I:Sp2-SP",  "SR:C01-MG{PS:CH1B}I:Sp1-SP",  "SR:C01-MG{PS:CH1B}I:Sp2-SP",
               "SR:C01-MG{PS:CH2B}I:Sp1-SP",  "SR:C01-MG{PS:CH2B}I:Sp2-SP",  "SR:C01-MG{PS:CL1A}I:Sp1-SP",  "SR:C01-MG{PS:CL1A}I:Sp2-SP",
               "SR:C01-MG{PS:CL2A}I:Sp1-SP",  "SR:C01-MG{PS:CL2A}I:Sp2-SP",  "SR:C01-MG{PS:CM1A}I:Sp1-SP",  "SR:C01-MG{PS:CM1A}I:Sp2-SP",
               "SR:C01-MG{PS:CM1B}I:Sp1-SP",  "SR:C01-MG{PS:CM1B}I:Sp2-SP",  "SR:C01-MG{PS:QH1B}I:Sp1-SP",  "SR:C01-MG{PS:QH2B}I:Sp1-SP",
               "SR:C01-MG{PS:QH3B}I:Sp1-SP",  "SR:C01-MG{PS:QL1A}I:Sp1-SP",  "SR:C01-MG{PS:QL2A}I:Sp1-SP",  "SR:C01-MG{PS:QL3A}I:Sp1-SP",
               "SR:C01-MG{PS:QM1A}I:Sp1-SP",  "SR:C01-MG{PS:QM1B}I:Sp1-SP",  "SR:C01-MG{PS:QM2A}I:Sp1-SP",  "SR:C01-MG{PS:QM2B}I:Sp1-SP",
               "SR:C01-MG{PS:SH4-P2}I:Sp1-SP",  "SR:C01-MG{PS:SM1A-P2}I:Sp1-SP",  "SR:C01-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C02-MG{PS:BT1A}I:Sp1-SP",
               "SR:C02-MG{PS:BT1A}I:Sp2-SP",  "SR:C02-MG{PS:CH1A}I:Sp1-SP",  "SR:C02-MG{PS:CH1A}I:Sp2-SP",  "SR:C02-MG{PS:CH2A}I:Sp1-SP",
               "SR:C02-MG{PS:CH2A}I:Sp2-SP",  "SR:C02-MG{PS:CL1B}I:Sp1-SP",  "SR:C02-MG{PS:CL1B}I:Sp2-SP",  "SR:C02-MG{PS:CL2B}I:Sp1-SP",
               "SR:C02-MG{PS:CL2B}I:Sp2-SP",  "SR:C02-MG{PS:CM1A}I:Sp1-SP",  "SR:C02-MG{PS:CM1A}I:Sp2-SP",  "SR:C02-MG{PS:CM1B}I:Sp1-SP",
               "SR:C02-MG{PS:CM1B}I:Sp2-SP",  "SR:C02-MG{PS:QH1A}I:Sp1-SP",  "SR:C02-MG{PS:QH2A}I:Sp1-SP",  "SR:C02-MG{PS:QH3A}I:Sp1-SP",
               "SR:C02-MG{PS:QL1B}I:Sp1-SP",  "SR:C02-MG{PS:QL2B}I:Sp1-SP",  "SR:C02-MG{PS:QL3B}I:Sp1-SP",  "SR:C02-MG{PS:QM1A}I:Sp1-SP",
                "SR:C02-MG{PS:QM1B}I:Sp1-SP",  "SR:C02-MG{PS:QM2A}I:Sp1-SP",  "SR:C02-MG{PS:QM2B}I:Sp1-SP",  "SR:C02-MG{PS:SM1B-P2}I:Sp1-SP",
                "SR:C02-MG{PS:SM2B-P2}I:Sp1-SP",  "SR:C02-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C03-MG{PS:BT1A}I:Sp1-SP",  "SR:C03-MG{PS:BT1A}I:Sp2-SP",
                "SR:C03-MG{PS:CH1B}I:Sp1-SP",  "SR:C03-MG{PS:CH1B}I:Sp2-SP",  "SR:C03-MG{PS:CH2B}I:Sp1-SP",  "SR:C03-MG{PS:CH2B}I:Sp2-SP",
                "SR:C03-MG{PS:CL1A}I:Sp1-SP",  "SR:C03-MG{PS:CL1A}I:Sp2-SP",  "SR:C03-MG{PS:CL2A}I:Sp1-SP",  "SR:C03-MG{PS:CL2A}I:Sp2-SP",
                "SR:C03-MG{PS:CM1A}I:Sp1-SP",  "SR:C03-MG{PS:CM1A}I:Sp2-SP",  "SR:C03-MG{PS:CM1B}I:Sp1-SP",  "SR:C03-MG{PS:CM1B}I:Sp2-SP",
                "SR:C03-MG{PS:D-SP}I:Sp1-SP",  "SR:C03-MG{PS:QH1B}I:Sp1-SP",  "SR:C03-MG{PS:QH2B}I:Sp1-SP",  "SR:C03-MG{PS:QH3B}I:Sp1-SP",
                "SR:C03-MG{PS:QL1A}I:Sp1-SP",  "SR:C03-MG{PS:QL2A}I:Sp1-SP",  "SR:C03-MG{PS:QL3A}I:Sp1-SP",  "SR:C03-MG{PS:QM1A}I:Sp1-SP",
                "SR:C03-MG{PS:QM1B}I:Sp1-SP",  "SR:C03-MG{PS:QM2A}I:Sp1-SP",  "SR:C03-MG{PS:QM2B}I:Sp1-SP",  "SR:C03-MG{PS:SL2-P2}I:Sp1-SP",
                "SR:C03-MG{PS:SL3-P2}I:Sp1-SP",  "SR:C03-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C04-MG{PS:BT1A}I:Sp1-SP",  "SR:C04-MG{PS:BT1A}I:Sp2-SP",
                "SR:C04-MG{PS:CH1A}I:Sp1-SP",  "SR:C04-MG{PS:CH1A}I:Sp2-SP",  "SR:C04-MG{PS:CH2A}I:Sp1-SP",  "SR:C04-MG{PS:CH2A}I:Sp2-SP",
                "SR:C04-MG{PS:CL1B}I:Sp1-SP",  "SR:C04-MG{PS:CL1B}I:Sp2-SP",  "SR:C04-MG{PS:CL2B}I:Sp1-SP",  "SR:C04-MG{PS:CL2B}I:Sp2-SP",
                "SR:C04-MG{PS:CM1A}I:Sp1-SP",  "SR:C04-MG{PS:CM1A}I:Sp2-SP",  "SR:C04-MG{PS:CM1B}I:Sp1-SP",  "SR:C04-MG{PS:CM1B}I:Sp2-SP",
                "SR:C04-MG{PS:QH1A}I:Sp1-SP",  "SR:C04-MG{PS:QH2A}I:Sp1-SP",  "SR:C04-MG{PS:QH3A}I:Sp1-SP",  "SR:C04-MG{PS:QL1B}I:Sp1-SP",
                "SR:C04-MG{PS:QL2B}I:Sp1-SP",  "SR:C04-MG{PS:QL3B}I:Sp1-SP",  "SR:C04-MG{PS:QM1A}I:Sp1-SP",  "SR:C04-MG{PS:QM1B}I:Sp1-SP",
                "SR:C04-MG{PS:QM2A}I:Sp1-SP",  "SR:C04-MG{PS:QM2B}I:Sp1-SP",  "SR:C04-MG{PS:SL1-P2}I:Sp1-SP",  "SR:C04-MG{PS:SQKH1A}I:Sp1-SP",
                "SR:C05-MG{PS:BT1A}I:Sp1-SP",  "SR:C05-MG{PS:BT1A}I:Sp2-SP",  "SR:C05-MG{PS:CH1B}I:Sp1-SP",  "SR:C05-MG{PS:CH1B}I:Sp2-SP",
                "SR:C05-MG{PS:CH2B}I:Sp1-SP",  "SR:C05-MG{PS:CH2B}I:Sp2-SP",  "SR:C05-MG{PS:CL1A}I:Sp1-SP",  "SR:C05-MG{PS:CL1A}I:Sp2-SP",
                "SR:C05-MG{PS:CL2A}I:Sp1-SP",  "SR:C05-MG{PS:CL2A}I:Sp2-SP",  "SR:C05-MG{PS:CM1A}I:Sp1-SP",  "SR:C05-MG{PS:CM1A}I:Sp2-SP",
                "SR:C05-MG{PS:CM1B}I:Sp1-SP",  "SR:C05-MG{PS:CM1B}I:Sp2-SP",  "SR:C05-MG{PS:QH1B}I:Sp1-SP",  "SR:C05-MG{PS:QH2B}I:Sp1-SP",
                "SR:C05-MG{PS:QH3B}I:Sp1-SP",  "SR:C05-MG{PS:QL1A}I:Sp1-SP",  "SR:C05-MG{PS:QL2A}I:Sp1-SP",  "SR:C05-MG{PS:QL3A}I:Sp1-SP",
                "SR:C05-MG{PS:QM1A}I:Sp1-SP",  "SR:C05-MG{PS:QM1B}I:Sp1-SP",  "SR:C05-MG{PS:QM2A}I:Sp1-SP",  "SR:C05-MG{PS:QM2B}I:Sp1-SP",
                "SR:C05-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C06-MG{PS:BT1A}I:Sp1-SP",  "SR:C06-MG{PS:BT1A}I:Sp2-SP",  "SR:C06-MG{PS:CH1A}I:Sp1-SP",
                "SR:C06-MG{PS:CH1A}I:Sp2-SP",  "SR:C06-MG{PS:CH2A}I:Sp1-SP",  "SR:C06-MG{PS:CH2A}I:Sp2-SP",  "SR:C06-MG{PS:CL1B}I:Sp1-SP",
                "SR:C06-MG{PS:CL1B}I:Sp2-SP",  "SR:C06-MG{PS:CL2B}I:Sp1-SP",  "SR:C06-MG{PS:CL2B}I:Sp2-SP",  "SR:C06-MG{PS:CM1A}I:Sp1-SP",
                "SR:C06-MG{PS:CM1A}I:Sp2-SP",  "SR:C06-MG{PS:CM1B}I:Sp1-SP",  "SR:C06-MG{PS:CM1B}I:Sp2-SP",  "SR:C06-MG{PS:QH1A}I:Sp1-SP",
                "SR:C06-MG{PS:QH2A}I:Sp1-SP",  "SR:C06-MG{PS:QH3A}I:Sp1-SP",  "SR:C06-MG{PS:QL1B}I:Sp1-SP",  "SR:C06-MG{PS:QL2B}I:Sp1-SP",
                "SR:C06-MG{PS:QL3B}I:Sp1-SP",  "SR:C06-MG{PS:QM1A}I:Sp1-SP",  "SR:C06-MG{PS:QM1B}I:Sp1-SP",  "SR:C06-MG{PS:QM2A}I:Sp1-SP",
                "SR:C06-MG{PS:QM2B}I:Sp1-SP",  "SR:C06-MG{PS:SH1-P3}I:Sp1-SP",  "SR:C06-MG{PS:SH3-P3}I:Sp1-SP",  "SR:C06-MG{PS:SQKH1A}I:Sp1-SP",
                "SR:C07-MG{PS:BT1A}I:Sp1-SP",  "SR:C07-MG{PS:BT1A}I:Sp2-SP",  "SR:C07-MG{PS:CH1B}I:Sp1-SP",  "SR:C07-MG{PS:CH1B}I:Sp2-SP",
                "SR:C07-MG{PS:CH2B}I:Sp1-SP",  "SR:C07-MG{PS:CH2B}I:Sp2-SP",  "SR:C07-MG{PS:CL1A}I:Sp1-SP",  "SR:C07-MG{PS:CL1A}I:Sp2-SP",
                "SR:C07-MG{PS:CL2A}I:Sp1-SP",  "SR:C07-MG{PS:CL2A}I:Sp2-SP",  "SR:C07-MG{PS:CM1A}I:Sp1-SP",  "SR:C07-MG{PS:CM1A}I:Sp2-SP",
                "SR:C07-MG{PS:CM1B}I:Sp1-SP",  "SR:C07-MG{PS:CM1B}I:Sp2-SP",  "SR:C07-MG{PS:QH1B}I:Sp1-SP",  "SR:C07-MG{PS:QH2B}I:Sp1-SP",
                "SR:C07-MG{PS:QH3B}I:Sp1-SP",  "SR:C07-MG{PS:QL1A}I:Sp1-SP",  "SR:C07-MG{PS:QL2A}I:Sp1-SP",  "SR:C07-MG{PS:QL3A}I:Sp1-SP",
                "SR:C07-MG{PS:QM1A}I:Sp1-SP",  "SR:C07-MG{PS:QM1B}I:Sp1-SP",  "SR:C07-MG{PS:QM2A}I:Sp1-SP",  "SR:C07-MG{PS:QM2B}I:Sp1-SP",
                "SR:C07-MG{PS:SH4-P3}I:Sp1-SP",  "SR:C07-MG{PS:SM1A-P3}I:Sp1-SP",  "SR:C07-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C08-MG{PS:BT1A}I:Sp1-SP",
                "SR:C08-MG{PS:BT1A}I:Sp2-SP",  "SR:C08-MG{PS:CH1A}I:Sp1-SP",  "SR:C08-MG{PS:CH1A}I:Sp2-SP",  "SR:C08-MG{PS:CH2A}I:Sp1-SP",
                "SR:C08-MG{PS:CH2A}I:Sp2-SP",  "SR:C08-MG{PS:CL1B}I:Sp1-SP",  "SR:C08-MG{PS:CL1B}I:Sp2-SP",  "SR:C08-MG{PS:CL2B}I:Sp1-SP",
                "SR:C08-MG{PS:CL2B}I:Sp2-SP",  "SR:C08-MG{PS:CM1A}I:Sp1-SP",  "SR:C08-MG{PS:CM1A}I:Sp2-SP",  "SR:C08-MG{PS:CM1B}I:Sp1-SP",
                "SR:C08-MG{PS:CM1B}I:Sp2-SP",  "SR:C08-MG{PS:QH1A}I:Sp1-SP",  "SR:C08-MG{PS:QH2A}I:Sp1-SP",  "SR:C08-MG{PS:QH3A}I:Sp1-SP",
                "SR:C08-MG{PS:QL1B}I:Sp1-SP",  "SR:C08-MG{PS:QL2B}I:Sp1-SP",  "SR:C08-MG{PS:QL3B}I:Sp1-SP",  "SR:C08-MG{PS:QM1A}I:Sp1-SP",
                "SR:C08-MG{PS:QM1B}I:Sp1-SP",  "SR:C08-MG{PS:QM2A}I:Sp1-SP",  "SR:C08-MG{PS:QM2B}I:Sp1-SP",  "SR:C08-MG{PS:SH1-DW08}I:Sp1-SP",
                "SR:C08-MG{PS:SH3-DW08}I:Sp1-SP",  "SR:C08-MG{PS:SH4-DW08}I:Sp1-SP",  "SR:C08-MG{PS:SM1B-P3}I:Sp1-SP",  "SR:C08-MG{PS:SM2B-P3}I:Sp1-SP",
                "SR:C08-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C09-MG{PS:BT1A}I:Sp1-SP",  "SR:C09-MG{PS:BT1A}I:Sp2-SP",  "SR:C09-MG{PS:CH1B}I:Sp1-SP",
                "SR:C09-MG{PS:CH1B}I:Sp2-SP",  "SR:C09-MG{PS:CH2B}I:Sp1-SP",  "SR:C09-MG{PS:CH2B}I:Sp2-SP",  "SR:C09-MG{PS:CL1A}I:Sp1-SP",
                "SR:C09-MG{PS:CL1A}I:Sp2-SP",  "SR:C09-MG{PS:CL2A}I:Sp1-SP",  "SR:C09-MG{PS:CL2A}I:Sp2-SP",  "SR:C09-MG{PS:CM1A}I:Sp1-SP",
                "SR:C09-MG{PS:CM1A}I:Sp2-SP",  "SR:C09-MG{PS:CM1B}I:Sp1-SP",  "SR:C09-MG{PS:CM1B}I:Sp2-SP",  "SR:C09-MG{PS:QH1B}I:Sp1-SP",
                "SR:C09-MG{PS:QH2B}I:Sp1-SP",  "SR:C09-MG{PS:QH3B}I:Sp1-SP",  "SR:C09-MG{PS:QL1A}I:Sp1-SP",  "SR:C09-MG{PS:QL2A}I:Sp1-SP",
                "SR:C09-MG{PS:QL3A}I:Sp1-SP",  "SR:C09-MG{PS:QM1A}I:Sp1-SP",  "SR:C09-MG{PS:QM1B}I:Sp1-SP",  "SR:C09-MG{PS:QM2A}I:Sp1-SP",
                "SR:C09-MG{PS:QM2B}I:Sp1-SP",  "SR:C09-MG{PS:SL2-P3}I:Sp1-SP",  "SR:C09-MG{PS:SL3-P3}I:Sp1-SP",  "SR:C09-MG{PS:SQKM1A}I:Sp1-SP",
                "SR:C10-MG{PS:BT1A}I:Sp1-SP",  "SR:C10-MG{PS:BT1A}I:Sp2-SP",  "SR:C10-MG{PS:CH1A}I:Sp1-SP",  "SR:C10-MG{PS:CH1A}I:Sp2-SP",
                "SR:C10-MG{PS:CH2A}I:Sp1-SP",  "SR:C10-MG{PS:CH2A}I:Sp2-SP",  "SR:C10-MG{PS:CL1B}I:Sp1-SP",  "SR:C10-MG{PS:CL1B}I:Sp2-SP",
                "SR:C10-MG{PS:CL2B}I:Sp1-SP",  "SR:C10-MG{PS:CL2B}I:Sp2-SP",  "SR:C10-MG{PS:CM1A}I:Sp1-SP",  "SR:C10-MG{PS:CM1A}I:Sp2-SP",
                "SR:C10-MG{PS:CM1B}I:Sp1-SP",  "SR:C10-MG{PS:CM1B}I:Sp2-SP",  "SR:C10-MG{PS:QH1A}I:Sp1-SP",  "SR:C10-MG{PS:QH2A}I:Sp1-SP",
                "SR:C10-MG{PS:QH3A}I:Sp1-SP",  "SR:C10-MG{PS:QL1B}I:Sp1-SP",  "SR:C10-MG{PS:QL2B}I:Sp1-SP",  "SR:C10-MG{PS:QL3B}I:Sp1-SP",
                "SR:C10-MG{PS:QM1A}I:Sp1-SP",  "SR:C10-MG{PS:QM1B}I:Sp1-SP",  "SR:C10-MG{PS:QM2A}I:Sp1-SP",  "SR:C10-MG{PS:QM2B}I:Sp1-SP",
                "SR:C10-MG{PS:SL1-P3}I:Sp1-SP",  "SR:C10-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C11-MG{PS:BT1A}I:Sp1-SP",  "SR:C11-MG{PS:BT1A}I:Sp2-SP",
                "SR:C11-MG{PS:CH1B}I:Sp1-SP",  "SR:C11-MG{PS:CH1B}I:Sp2-SP",  "SR:C11-MG{PS:CH2B}I:Sp1-SP",  "SR:C11-MG{PS:CH2B}I:Sp2-SP",
                "SR:C11-MG{PS:CL1A}I:Sp1-SP",  "SR:C11-MG{PS:CL1A}I:Sp2-SP",  "SR:C11-MG{PS:CL2A}I:Sp1-SP",  "SR:C11-MG{PS:CL2A}I:Sp2-SP",
                "SR:C11-MG{PS:CM1A}I:Sp1-SP",  "SR:C11-MG{PS:CM1A}I:Sp2-SP",  "SR:C11-MG{PS:CM1B}I:Sp1-SP",  "SR:C11-MG{PS:CM1B}I:Sp2-SP",
                "SR:C11-MG{PS:QH1B}I:Sp1-SP",  "SR:C11-MG{PS:QH2B}I:Sp1-SP",  "SR:C11-MG{PS:QH3B}I:Sp1-SP",  "SR:C11-MG{PS:QL1A}I:Sp1-SP",
                "SR:C11-MG{PS:QL2A}I:Sp1-SP",  "SR:C11-MG{PS:QL3A}I:Sp1-SP",  "SR:C11-MG{PS:QM1A}I:Sp1-SP",  "SR:C11-MG{PS:QM1B}I:Sp1-SP",
                "SR:C11-MG{PS:QM2A}I:Sp1-SP",  "SR:C11-MG{PS:QM2B}I:Sp1-SP",  "SR:C11-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C12-MG{PS:BT1A}I:Sp1-SP",
                "SR:C12-MG{PS:BT1A}I:Sp2-SP",  "SR:C12-MG{PS:CH1A}I:Sp1-SP",  "SR:C12-MG{PS:CH1A}I:Sp2-SP",  "SR:C12-MG{PS:CH2A}I:Sp1-SP",
                "SR:C12-MG{PS:CH2A}I:Sp2-SP",  "SR:C12-MG{PS:CL1B}I:Sp1-SP",  "SR:C12-MG{PS:CL1B}I:Sp2-SP",  "SR:C12-MG{PS:CL2B}I:Sp1-SP",
                "SR:C12-MG{PS:CL2B}I:Sp2-SP",  "SR:C12-MG{PS:CM1A}I:Sp1-SP",  "SR:C12-MG{PS:CM1A}I:Sp2-SP",  "SR:C12-MG{PS:CM1B}I:Sp1-SP",
                "SR:C12-MG{PS:CM1B}I:Sp2-SP",  "SR:C12-MG{PS:QH1A}I:Sp1-SP",  "SR:C12-MG{PS:QH2A}I:Sp1-SP",  "SR:C12-MG{PS:QH3A}I:Sp1-SP",
                "SR:C12-MG{PS:QL1B}I:Sp1-SP",  "SR:C12-MG{PS:QL2B}I:Sp1-SP",  "SR:C12-MG{PS:QL3B}I:Sp1-SP",  "SR:C12-MG{PS:QM1A}I:Sp1-SP",
                "SR:C12-MG{PS:QM1B}I:Sp1-SP",  "SR:C12-MG{PS:QM2A}I:Sp1-SP",  "SR:C12-MG{PS:QM2B}I:Sp1-SP",  "SR:C12-MG{PS:SH1-P4}I:Sp1-SP",
                "SR:C12-MG{PS:SH3-P4}I:Sp1-SP",  "SR:C12-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C13-MG{PS:BT1A}I:Sp1-SP",  "SR:C13-MG{PS:BT1A}I:Sp2-SP",
                "SR:C13-MG{PS:CH1B}I:Sp1-SP",  "SR:C13-MG{PS:CH1B}I:Sp2-SP",  "SR:C13-MG{PS:CH2B}I:Sp1-SP",  "SR:C13-MG{PS:CH2B}I:Sp2-SP",
                "SR:C13-MG{PS:CL1A}I:Sp1-SP",  "SR:C13-MG{PS:CL1A}I:Sp2-SP",  "SR:C13-MG{PS:CL2A}I:Sp1-SP",  "SR:C13-MG{PS:CL2A}I:Sp2-SP",
                "SR:C13-MG{PS:CM1A}I:Sp1-SP",  "SR:C13-MG{PS:CM1A}I:Sp2-SP",  "SR:C13-MG{PS:CM1B}I:Sp1-SP",  "SR:C13-MG{PS:CM1B}I:Sp2-SP",
                "SR:C13-MG{PS:QH1B}I:Sp1-SP",  "SR:C13-MG{PS:QH2B}I:Sp1-SP",  "SR:C13-MG{PS:QH3B}I:Sp1-SP",  "SR:C13-MG{PS:QL1A}I:Sp1-SP",
                "SR:C13-MG{PS:QL2A}I:Sp1-SP",  "SR:C13-MG{PS:QL3A}I:Sp1-SP",  "SR:C13-MG{PS:QM1A}I:Sp1-SP",  "SR:C13-MG{PS:QM1B}I:Sp1-SP",
                "SR:C13-MG{PS:QM2A}I:Sp1-SP",  "SR:C13-MG{PS:QM2B}I:Sp1-SP",  "SR:C13-MG{PS:SH4-P4}I:Sp1-SP",  "SR:C13-MG{PS:SM1A-P4}I:Sp1-SP",
                "SR:C13-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C14-MG{PS:BT1A}I:Sp1-SP",  "SR:C14-MG{PS:BT1A}I:Sp2-SP",  "SR:C14-MG{PS:CH1A}I:Sp1-SP",
                "SR:C14-MG{PS:CH1A}I:Sp2-SP",  "SR:C14-MG{PS:CH2A}I:Sp1-SP",  "SR:C14-MG{PS:CH2A}I:Sp2-SP",  "SR:C14-MG{PS:CL1B}I:Sp1-SP",
                "SR:C14-MG{PS:CL1B}I:Sp2-SP",  "SR:C14-MG{PS:CL2B}I:Sp1-SP",  "SR:C14-MG{PS:CL2B}I:Sp2-SP",  "SR:C14-MG{PS:CM1A}I:Sp1-SP",
                "SR:C14-MG{PS:CM1A}I:Sp2-SP",  "SR:C14-MG{PS:CM1B}I:Sp1-SP",  "SR:C14-MG{PS:CM1B}I:Sp2-SP",  "SR:C14-MG{PS:QH1A}I:Sp1-SP",
                "SR:C14-MG{PS:QH2A}I:Sp1-SP",  "SR:C14-MG{PS:QH3A}I:Sp1-SP",  "SR:C14-MG{PS:QL1B}I:Sp1-SP",  "SR:C14-MG{PS:QL2B}I:Sp1-SP",
                "SR:C14-MG{PS:QL3B}I:Sp1-SP",  "SR:C14-MG{PS:QM1A}I:Sp1-SP",  "SR:C14-MG{PS:QM1B}I:Sp1-SP",  "SR:C14-MG{PS:QM2A}I:Sp1-SP",
                "SR:C14-MG{PS:QM2B}I:Sp1-SP",  "SR:C14-MG{PS:SM1B-P4}I:Sp1-SP",  "SR:C14-MG{PS:SM2B-P4}I:Sp1-SP",  "SR:C14-MG{PS:SQKH1A}I:Sp1-SP",
                "SR:C15-MG{PS:BT1A}I:Sp1-SP",  "SR:C15-MG{PS:BT1A}I:Sp2-SP",  "SR:C15-MG{PS:CH1B}I:Sp1-SP",  "SR:C15-MG{PS:CH1B}I:Sp2-SP",
                "SR:C15-MG{PS:CH2B}I:Sp1-SP",  "SR:C15-MG{PS:CH2B}I:Sp2-SP",  "SR:C15-MG{PS:CL1A}I:Sp1-SP",  "SR:C15-MG{PS:CL1A}I:Sp2-SP",
                "SR:C15-MG{PS:CL2A}I:Sp1-SP",  "SR:C15-MG{PS:CL2A}I:Sp2-SP",  "SR:C15-MG{PS:CM1A}I:Sp1-SP",  "SR:C15-MG{PS:CM1A}I:Sp2-SP",
                "SR:C15-MG{PS:CM1B}I:Sp1-SP",  "SR:C15-MG{PS:CM1B}I:Sp2-SP",  "SR:C15-MG{PS:QH1B}I:Sp1-SP",  "SR:C15-MG{PS:QH2B}I:Sp1-SP",
                "SR:C15-MG{PS:QH3B}I:Sp1-SP",  "SR:C15-MG{PS:QL1A}I:Sp1-SP",  "SR:C15-MG{PS:QL2A}I:Sp1-SP",  "SR:C15-MG{PS:QL3A}I:Sp1-SP",
                "SR:C15-MG{PS:QM1A}I:Sp1-SP",  "SR:C15-MG{PS:QM1B}I:Sp1-SP",  "SR:C15-MG{PS:QM2A}I:Sp1-SP",  "SR:C15-MG{PS:QM2B}I:Sp1-SP",
                "SR:C15-MG{PS:SL2-P4}I:Sp1-SP",  "SR:C15-MG{PS:SL3-P4}I:Sp1-SP",  "SR:C15-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C16-MG{PS:BT1A}I:Sp1-SP",
                "SR:C16-MG{PS:BT1A}I:Sp2-SP",  "SR:C16-MG{PS:CH1A}I:Sp1-SP",  "SR:C16-MG{PS:CH1A}I:Sp2-SP",  "SR:C16-MG{PS:CH2A}I:Sp1-SP",
                "SR:C16-MG{PS:CH2A}I:Sp2-SP",  "SR:C16-MG{PS:CL1B}I:Sp1-SP",  "SR:C16-MG{PS:CL1B}I:Sp2-SP",  "SR:C16-MG{PS:CL2B}I:Sp1-SP",
                "SR:C16-MG{PS:CL2B}I:Sp2-SP",  "SR:C16-MG{PS:CM1A}I:Sp1-SP",  "SR:C16-MG{PS:CM1A}I:Sp2-SP",  "SR:C16-MG{PS:CM1B}I:Sp1-SP",
                "SR:C16-MG{PS:CM1B}I:Sp2-SP",  "SR:C16-MG{PS:QH1A}I:Sp1-SP",  "SR:C16-MG{PS:QH2A}I:Sp1-SP",  "SR:C16-MG{PS:QH3A}I:Sp1-SP",
                "SR:C16-MG{PS:QL1B}I:Sp1-SP",  "SR:C16-MG{PS:QL2B}I:Sp1-SP",  "SR:C16-MG{PS:QL3B}I:Sp1-SP",  "SR:C16-MG{PS:QM1A}I:Sp1-SP",
                "SR:C16-MG{PS:QM1B}I:Sp1-SP",  "SR:C16-MG{PS:QM2A}I:Sp1-SP",  "SR:C16-MG{PS:QM2B}I:Sp1-SP",  "SR:C16-MG{PS:SL1-P4}I:Sp1-SP",
                "SR:C16-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C17-MG{PS:BT1A}I:Sp1-SP",  "SR:C17-MG{PS:BT1A}I:Sp2-SP",  "SR:C17-MG{PS:CH1B}I:Sp1-SP",
                "SR:C17-MG{PS:CH1B}I:Sp2-SP",  "SR:C17-MG{PS:CH2B}I:Sp1-SP",  "SR:C17-MG{PS:CH2B}I:Sp2-SP",  "SR:C17-MG{PS:CL1A}I:Sp1-SP",
                "SR:C17-MG{PS:CL1A}I:Sp2-SP",  "SR:C17-MG{PS:CL2A}I:Sp1-SP",  "SR:C17-MG{PS:CL2A}I:Sp2-SP",  "SR:C17-MG{PS:CM1A}I:Sp1-SP",
                "SR:C17-MG{PS:CM1A}I:Sp2-SP",  "SR:C17-MG{PS:CM1B}I:Sp1-SP",  "SR:C17-MG{PS:CM1B}I:Sp2-SP",  "SR:C17-MG{PS:QH1B}I:Sp1-SP",
                "SR:C17-MG{PS:QH2B}I:Sp1-SP",  "SR:C17-MG{PS:QH3B}I:Sp1-SP",  "SR:C17-MG{PS:QL1A}I:Sp1-SP",  "SR:C17-MG{PS:QL2A}I:Sp1-SP",
                "SR:C17-MG{PS:QL3A}I:Sp1-SP",  "SR:C17-MG{PS:QM1A}I:Sp1-SP",  "SR:C17-MG{PS:QM1B}I:Sp1-SP",  "SR:C17-MG{PS:QM2A}I:Sp1-SP",
                "SR:C17-MG{PS:QM2B}I:Sp1-SP",  "SR:C17-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C18-MG{PS:BT1A}I:Sp1-SP",  "SR:C18-MG{PS:BT1A}I:Sp2-SP",
                "SR:C18-MG{PS:CH1A}I:Sp1-SP",  "SR:C18-MG{PS:CH1A}I:Sp2-SP",  "SR:C18-MG{PS:CH2A}I:Sp1-SP",  "SR:C18-MG{PS:CH2A}I:Sp2-SP",
                "SR:C18-MG{PS:CL1B}I:Sp1-SP",  "SR:C18-MG{PS:CL1B}I:Sp2-SP",  "SR:C18-MG{PS:CL2B}I:Sp1-SP",  "SR:C18-MG{PS:CL2B}I:Sp2-SP",
                "SR:C18-MG{PS:CM1A}I:Sp1-SP",  "SR:C18-MG{PS:CM1A}I:Sp2-SP",  "SR:C18-MG{PS:CM1B}I:Sp1-SP",  "SR:C18-MG{PS:CM1B}I:Sp2-SP",
                "SR:C18-MG{PS:QH1A}I:Sp1-SP",  "SR:C18-MG{PS:QH2A}I:Sp1-SP",  "SR:C18-MG{PS:QH3A}I:Sp1-SP",  "SR:C18-MG{PS:QL1B}I:Sp1-SP",
                "SR:C18-MG{PS:QL2B}I:Sp1-SP",  "SR:C18-MG{PS:QL3B}I:Sp1-SP",  "SR:C18-MG{PS:QM1A}I:Sp1-SP",  "SR:C18-MG{PS:QM1B}I:Sp1-SP",
                "SR:C18-MG{PS:QM2A}I:Sp1-SP",  "SR:C18-MG{PS:QM2B}I:Sp1-SP",  "SR:C18-MG{PS:SH1-DW18}I:Sp1-SP",  "SR:C18-MG{PS:SH1-P5}I:Sp1-SP",
                "SR:C18-MG{PS:SH3-DW18}I:Sp1-SP",  "SR:C18-MG{PS:SH3-P5}I:Sp1-SP",  "SR:C18-MG{PS:SH4-DW18}I:Sp1-SP",  "SR:C18-MG{PS:SQKH1A}I:Sp1-SP",
                "SR:C19-MG{PS:BT1A}I:Sp1-SP",  "SR:C19-MG{PS:BT1A}I:Sp2-SP",  "SR:C19-MG{PS:CH1B}I:Sp1-SP",  "SR:C19-MG{PS:CH1B}I:Sp2-SP",
                "SR:C19-MG{PS:CH2B}I:Sp1-SP",  "SR:C19-MG{PS:CH2B}I:Sp2-SP",  "SR:C19-MG{PS:CL1A}I:Sp1-SP",  "SR:C19-MG{PS:CL1A}I:Sp2-SP",
                "SR:C19-MG{PS:CL2A}I:Sp1-SP",  "SR:C19-MG{PS:CL2A}I:Sp2-SP",  "SR:C19-MG{PS:CM1A}I:Sp1-SP",  "SR:C19-MG{PS:CM1A}I:Sp2-SP",
                "SR:C19-MG{PS:CM1B}I:Sp1-SP",  "SR:C19-MG{PS:CM1B}I:Sp2-SP",  "SR:C19-MG{PS:QH1B}I:Sp1-SP",  "SR:C19-MG{PS:QH2B}I:Sp1-SP",
                "SR:C19-MG{PS:QH3B}I:Sp1-SP",  "SR:C19-MG{PS:QL1A}I:Sp1-SP",  "SR:C19-MG{PS:QL2A}I:Sp1-SP",  "SR:C19-MG{PS:QL3A}I:Sp1-SP",
                "SR:C19-MG{PS:QM1A}I:Sp1-SP",  "SR:C19-MG{PS:QM1B}I:Sp1-SP",  "SR:C19-MG{PS:QM2A}I:Sp1-SP",  "SR:C19-MG{PS:QM2B}I:Sp1-SP",
                "SR:C19-MG{PS:SH4-P5}I:Sp1-SP",  "SR:C19-MG{PS:SM1A-P5}I:Sp1-SP",  "SR:C19-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C20-MG{PS:BT1A}I:Sp1-SP",
                "SR:C20-MG{PS:BT1A}I:Sp2-SP",  "SR:C20-MG{PS:CH1A}I:Sp1-SP",  "SR:C20-MG{PS:CH1A}I:Sp2-SP",  "SR:C20-MG{PS:CH2A}I:Sp1-SP",
                "SR:C20-MG{PS:CH2A}I:Sp2-SP",  "SR:C20-MG{PS:CL1B}I:Sp1-SP",  "SR:C20-MG{PS:CL1B}I:Sp2-SP",  "SR:C20-MG{PS:CL2B}I:Sp1-SP",
                "SR:C20-MG{PS:CL2B}I:Sp2-SP",  "SR:C20-MG{PS:CM1A}I:Sp1-SP",  "SR:C20-MG{PS:CM1A}I:Sp2-SP",  "SR:C20-MG{PS:CM1B}I:Sp1-SP",
                "SR:C20-MG{PS:CM1B}I:Sp2-SP",  "SR:C20-MG{PS:QH1A}I:Sp1-SP",  "SR:C20-MG{PS:QH2A}I:Sp1-SP",  "SR:C20-MG{PS:QH3A}I:Sp1-SP",
                "SR:C20-MG{PS:QL1B}I:Sp1-SP",  "SR:C20-MG{PS:QL2B}I:Sp1-SP",  "SR:C20-MG{PS:QL3B}I:Sp1-SP",  "SR:C20-MG{PS:QM1A}I:Sp1-SP",
                "SR:C20-MG{PS:QM1B}I:Sp1-SP",  "SR:C20-MG{PS:QM2A}I:Sp1-SP",  "SR:C20-MG{PS:QM2B}I:Sp1-SP",  "SR:C20-MG{PS:SM1B-P5}I:Sp1-SP",
                "SR:C20-MG{PS:SM2B-P5}I:Sp1-SP",  "SR:C20-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C21-MG{PS:BT1A}I:Sp1-SP",  "SR:C21-MG{PS:BT1A}I:Sp2-SP",
                "SR:C21-MG{PS:CH1B}I:Sp1-SP",  "SR:C21-MG{PS:CH1B}I:Sp2-SP",  "SR:C21-MG{PS:CH2B}I:Sp1-SP",  "SR:C21-MG{PS:CH2B}I:Sp2-SP",
                "SR:C21-MG{PS:CL1A}I:Sp1-SP",  "SR:C21-MG{PS:CL1A}I:Sp2-SP",  "SR:C21-MG{PS:CL2A}I:Sp1-SP",  "SR:C21-MG{PS:CL2A}I:Sp2-SP",
                "SR:C21-MG{PS:CM1A}I:Sp1-SP",  "SR:C21-MG{PS:CM1A}I:Sp2-SP",  "SR:C21-MG{PS:CM1B}I:Sp1-SP",  "SR:C21-MG{PS:CM1B}I:Sp2-SP",
                "SR:C21-MG{PS:QH1B}I:Sp1-SP",  "SR:C21-MG{PS:QH2B}I:Sp1-SP",  "SR:C21-MG{PS:QH3B}I:Sp1-SP",  "SR:C21-MG{PS:QL1A}I:Sp1-SP",
                "SR:C21-MG{PS:QL2A}I:Sp1-SP",  "SR:C21-MG{PS:QL3A}I:Sp1-SP",  "SR:C21-MG{PS:QM1A}I:Sp1-SP",  "SR:C21-MG{PS:QM1B}I:Sp1-SP",
                "SR:C21-MG{PS:QM2A}I:Sp1-SP",  "SR:C21-MG{PS:QM2B}I:Sp1-SP",  "SR:C21-MG{PS:SL2-P5}I:Sp1-SP",  "SR:C21-MG{PS:SL3-P5}I:Sp1-SP",
                "SR:C21-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C22-MG{PS:BT1A}I:Sp1-SP",  "SR:C22-MG{PS:BT1A}I:Sp2-SP",  "SR:C22-MG{PS:CH1A}I:Sp1-SP",
                "SR:C22-MG{PS:CH1A}I:Sp2-SP",  "SR:C22-MG{PS:CH2A}I:Sp1-SP",  "SR:C22-MG{PS:CH2A}I:Sp2-SP",  "SR:C22-MG{PS:CL1B}I:Sp1-SP",
                "SR:C22-MG{PS:CL1B}I:Sp2-SP",  "SR:C22-MG{PS:CL2B}I:Sp1-SP",  "SR:C22-MG{PS:CL2B}I:Sp2-SP",  "SR:C22-MG{PS:CM1A}I:Sp1-SP",
                "SR:C22-MG{PS:CM1A}I:Sp2-SP",  "SR:C22-MG{PS:CM1B}I:Sp1-SP",  "SR:C22-MG{PS:CM1B}I:Sp2-SP",  "SR:C22-MG{PS:QH1A}I:Sp1-SP",
                "SR:C22-MG{PS:QH2A}I:Sp1-SP",  "SR:C22-MG{PS:QH3A}I:Sp1-SP",  "SR:C22-MG{PS:QL1B}I:Sp1-SP",  "SR:C22-MG{PS:QL2B}I:Sp1-SP",
                "SR:C22-MG{PS:QL3B}I:Sp1-SP",  "SR:C22-MG{PS:QM1A}I:Sp1-SP",  "SR:C22-MG{PS:QM1B}I:Sp1-SP",  "SR:C22-MG{PS:QM2A}I:Sp1-SP",
                "SR:C22-MG{PS:QM2B}I:Sp1-SP",  "SR:C22-MG{PS:SL1-P5}I:Sp1-SP",  "SR:C22-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C23-MG{PS:BT1A}I:Sp1-SP",
                "SR:C23-MG{PS:BT1A}I:Sp2-SP",  "SR:C23-MG{PS:CH1B}I:Sp1-SP",  "SR:C23-MG{PS:CH1B}I:Sp2-SP",  "SR:C23-MG{PS:CH2B}I:Sp1-SP",
                "SR:C23-MG{PS:CH2B}I:Sp2-SP",  "SR:C23-MG{PS:CL1A}I:Sp1-SP",  "SR:C23-MG{PS:CL1A}I:Sp2-SP",  "SR:C23-MG{PS:CL2A}I:Sp1-SP",
                "SR:C23-MG{PS:CL2A}I:Sp2-SP",  "SR:C23-MG{PS:CM1A}I:Sp1-SP",  "SR:C23-MG{PS:CM1A}I:Sp2-SP",  "SR:C23-MG{PS:CM1B}I:Sp1-SP",
                "SR:C23-MG{PS:CM1B}I:Sp2-SP",  "SR:C23-MG{PS:QH1B}I:Sp1-SP",  "SR:C23-MG{PS:QH2B}I:Sp1-SP",  "SR:C23-MG{PS:QH3B}I:Sp1-SP",
                "SR:C23-MG{PS:QL1A}I:Sp1-SP",  "SR:C23-MG{PS:QL2A}I:Sp1-SP",  "SR:C23-MG{PS:QL3A}I:Sp1-SP",  "SR:C23-MG{PS:QM1A}I:Sp1-SP",
                "SR:C23-MG{PS:QM1B}I:Sp1-SP",  "SR:C23-MG{PS:QM2A}I:Sp1-SP",  "SR:C23-MG{PS:QM2B}I:Sp1-SP",  "SR:C23-MG{PS:SQKM1A}I:Sp1-SP",
                "SR:C24-MG{PS:BT1A}I:Sp1-SP",  "SR:C24-MG{PS:BT1A}I:Sp2-SP",  "SR:C24-MG{PS:CH1A}I:Sp1-SP",  "SR:C24-MG{PS:CH1A}I:Sp2-SP",
                "SR:C24-MG{PS:CH2A}I:Sp1-SP",  "SR:C24-MG{PS:CH2A}I:Sp2-SP",  "SR:C24-MG{PS:CL1B}I:Sp1-SP",  "SR:C24-MG{PS:CL1B}I:Sp2-SP",
                "SR:C24-MG{PS:CL2B}I:Sp1-SP",  "SR:C24-MG{PS:CL2B}I:Sp2-SP",  "SR:C24-MG{PS:CM1A}I:Sp1-SP",  "SR:C24-MG{PS:CM1A}I:Sp2-SP",
                "SR:C24-MG{PS:CM1B}I:Sp1-SP",  "SR:C24-MG{PS:CM1B}I:Sp2-SP",  "SR:C24-MG{PS:QH1A}I:Sp1-SP",  "SR:C24-MG{PS:QH2A}I:Sp1-SP",
                "SR:C24-MG{PS:QH3A}I:Sp1-SP",  "SR:C24-MG{PS:QL1B}I:Sp1-SP",  "SR:C24-MG{PS:QL2B}I:Sp1-SP",  "SR:C24-MG{PS:QL3B}I:Sp1-SP",
                "SR:C24-MG{PS:QM1A}I:Sp1-SP",  "SR:C24-MG{PS:QM1B}I:Sp1-SP",  "SR:C24-MG{PS:QM2A}I:Sp1-SP",  "SR:C24-MG{PS:QM2B}I:Sp1-SP",
                "SR:C24-MG{PS:SH1-P1}I:Sp1-SP",  "SR:C24-MG{PS:SH3-P1}I:Sp1-SP",  "SR:C24-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C25-MG{PS:BT1A}I:Sp1-SP",
                "SR:C25-MG{PS:BT1A}I:Sp2-SP",  "SR:C25-MG{PS:CH1B}I:Sp1-SP",  "SR:C25-MG{PS:CH1B}I:Sp2-SP",  "SR:C25-MG{PS:CH2B}I:Sp1-SP",
                "SR:C25-MG{PS:CH2B}I:Sp2-SP",  "SR:C25-MG{PS:CL1A}I:Sp1-SP",  "SR:C25-MG{PS:CL1A}I:Sp2-SP",  "SR:C25-MG{PS:CL2A}I:Sp1-SP",
                "SR:C25-MG{PS:CL2A}I:Sp2-SP",  "SR:C25-MG{PS:CM1A}I:Sp1-SP",  "SR:C25-MG{PS:CM1A}I:Sp2-SP",  "SR:C25-MG{PS:CM1B}I:Sp1-SP",
                "SR:C25-MG{PS:CM1B}I:Sp2-SP",  "SR:C25-MG{PS:QH1B}I:Sp1-SP",  "SR:C25-MG{PS:QH2B}I:Sp1-SP",  "SR:C25-MG{PS:QH3B}I:Sp1-SP",
                "SR:C25-MG{PS:QL1A}I:Sp1-SP",  "SR:C25-MG{PS:QL2A}I:Sp1-SP",  "SR:C25-MG{PS:QL3A}I:Sp1-SP",  "SR:C25-MG{PS:QM1A}I:Sp1-SP",
                "SR:C25-MG{PS:QM1B}I:Sp1-SP",  "SR:C25-MG{PS:QM2A}I:Sp1-SP",  "SR:C25-MG{PS:QM2B}I:Sp1-SP",  "SR:C25-MG{PS:SH4-P1}I:Sp1-SP",
                "SR:C25-MG{PS:SM1A-P1}I:Sp1-SP",  "SR:C25-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C26-MG{PS:BT1A}I:Sp1-SP",  "SR:C26-MG{PS:BT1A}I:Sp2-SP",
                "SR:C26-MG{PS:CH1A}I:Sp1-SP",  "SR:C26-MG{PS:CH1A}I:Sp2-SP",  "SR:C26-MG{PS:CH2A}I:Sp1-SP",  "SR:C26-MG{PS:CH2A}I:Sp2-SP",
                "SR:C26-MG{PS:CL1B}I:Sp1-SP",  "SR:C26-MG{PS:CL1B}I:Sp2-SP",  "SR:C26-MG{PS:CL2B}I:Sp1-SP",  "SR:C26-MG{PS:CL2B}I:Sp2-SP",
                "SR:C26-MG{PS:CM1A}I:Sp1-SP",  "SR:C26-MG{PS:CM1A}I:Sp2-SP",  "SR:C26-MG{PS:CM1B}I:Sp1-SP",  "SR:C26-MG{PS:CM1B}I:Sp2-SP",
                "SR:C26-MG{PS:QH1A}I:Sp1-SP",  "SR:C26-MG{PS:QH2A}I:Sp1-SP",  "SR:C26-MG{PS:QH3A}I:Sp1-SP",  "SR:C26-MG{PS:QL1B}I:Sp1-SP",
                "SR:C26-MG{PS:QL2B}I:Sp1-SP",  "SR:C26-MG{PS:QL3B}I:Sp1-SP",  "SR:C26-MG{PS:QM1A}I:Sp1-SP",  "SR:C26-MG{PS:QM1B}I:Sp1-SP",
                "SR:C26-MG{PS:QM2A}I:Sp1-SP",  "SR:C26-MG{PS:QM2B}I:Sp1-SP",  "SR:C26-MG{PS:SM1B-P1}I:Sp1-SP",  "SR:C26-MG{PS:SM2B-P1}I:Sp1-SP",
                "SR:C26-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C27-MG{PS:BT1A}I:Sp1-SP",  "SR:C27-MG{PS:BT1A}I:Sp2-SP",  "SR:C27-MG{PS:CH1B}I:Sp1-SP",
                "SR:C27-MG{PS:CH1B}I:Sp2-SP",  "SR:C27-MG{PS:CH2B}I:Sp1-SP",  "SR:C27-MG{PS:CH2B}I:Sp2-SP",  "SR:C27-MG{PS:CL1A}I:Sp1-SP",
                "SR:C27-MG{PS:CL1A}I:Sp2-SP",  "SR:C27-MG{PS:CL2A}I:Sp1-SP",  "SR:C27-MG{PS:CL2A}I:Sp2-SP",  "SR:C27-MG{PS:CM1A}I:Sp1-SP",
                "SR:C27-MG{PS:CM1A}I:Sp2-SP",  "SR:C27-MG{PS:CM1B}I:Sp1-SP",  "SR:C27-MG{PS:CM1B}I:Sp2-SP",  "SR:C27-MG{PS:QH1B}I:Sp1-SP",
                "SR:C27-MG{PS:QH2B}I:Sp1-SP",  "SR:C27-MG{PS:QH3B}I:Sp1-SP",  "SR:C27-MG{PS:QL1A}I:Sp1-SP",  "SR:C27-MG{PS:QL2A}I:Sp1-SP",
                "SR:C27-MG{PS:QL3A}I:Sp1-SP",  "SR:C27-MG{PS:QM1A}I:Sp1-SP",  "SR:C27-MG{PS:QM1B}I:Sp1-SP",  "SR:C27-MG{PS:QM2A}I:Sp1-SP",
                "SR:C27-MG{PS:QM2B}I:Sp1-SP",  "SR:C27-MG{PS:SL2-P1}I:Sp1-SP",  "SR:C27-MG{PS:SL3-P1}I:Sp1-SP",  "SR:C27-MG{PS:SQKM1A}I:Sp1-SP",
                "SR:C28-MG{PS:BT1A}I:Sp1-SP",  "SR:C28-MG{PS:BT1A}I:Sp2-SP",  "SR:C28-MG{PS:CH1A}I:Sp1-SP",  "SR:C28-MG{PS:CH1A}I:Sp2-SP",
                "SR:C28-MG{PS:CH2A}I:Sp1-SP",  "SR:C28-MG{PS:CH2A}I:Sp2-SP",  "SR:C28-MG{PS:CL1B}I:Sp1-SP",  "SR:C28-MG{PS:CL1B}I:Sp2-SP",
                "SR:C28-MG{PS:CL2B}I:Sp1-SP",  "SR:C28-MG{PS:CL2B}I:Sp2-SP",  "SR:C28-MG{PS:CM1A}I:Sp1-SP",  "SR:C28-MG{PS:CM1A}I:Sp2-SP",
                "SR:C28-MG{PS:CM1B}I:Sp1-SP",  "SR:C28-MG{PS:CM1B}I:Sp2-SP",  "SR:C28-MG{PS:QH1A}I:Sp1-SP",  "SR:C28-MG{PS:QH2A}I:Sp1-SP",
                "SR:C28-MG{PS:QH3A}I:Sp1-SP",  "SR:C28-MG{PS:QL1B}I:Sp1-SP",  "SR:C28-MG{PS:QL2B}I:Sp1-SP",  "SR:C28-MG{PS:QL3B}I:Sp1-SP",
                "SR:C28-MG{PS:QM1A}I:Sp1-SP",  "SR:C28-MG{PS:QM1B}I:Sp1-SP",  "SR:C28-MG{PS:QM2A}I:Sp1-SP",  "SR:C28-MG{PS:QM2B}I:Sp1-SP",
                "SR:C28-MG{PS:SH1-DW28}I:Sp1-SP",  "SR:C28-MG{PS:SH3-DW28}I:Sp1-SP",  "SR:C28-MG{PS:SH4-DW28}I:Sp1-SP",  "SR:C28-MG{PS:SL1-P1}I:Sp1-SP",
                "SR:C28-MG{PS:SQKH1A}I:Sp1-SP",  "SR:C29-MG{PS:BT1A}I:Sp1-SP",  "SR:C29-MG{PS:BT1A}I:Sp2-SP",  "SR:C29-MG{PS:CH1B}I:Sp1-SP",
                "SR:C29-MG{PS:CH1B}I:Sp2-SP",  "SR:C29-MG{PS:CH2B}I:Sp1-SP",  "SR:C29-MG{PS:CH2B}I:Sp2-SP",  "SR:C29-MG{PS:CL1A}I:Sp1-SP",
                "SR:C29-MG{PS:CL1A}I:Sp2-SP",  "SR:C29-MG{PS:CL2A}I:Sp1-SP",  "SR:C29-MG{PS:CL2A}I:Sp2-SP",  "SR:C29-MG{PS:CM1A}I:Sp1-SP",
                "SR:C29-MG{PS:CM1A}I:Sp2-SP",  "SR:C29-MG{PS:CM1B}I:Sp1-SP",  "SR:C29-MG{PS:CM1B}I:Sp2-SP",  "SR:C29-MG{PS:QH1B}I:Sp1-SP",
                "SR:C29-MG{PS:QH2B}I:Sp1-SP",  "SR:C29-MG{PS:QH3B}I:Sp1-SP",  "SR:C29-MG{PS:QL1A}I:Sp1-SP",  "SR:C29-MG{PS:QL2A}I:Sp1-SP",
                "SR:C29-MG{PS:QL3A}I:Sp1-SP",  "SR:C29-MG{PS:QM1A}I:Sp1-SP",  "SR:C29-MG{PS:QM1B}I:Sp1-SP",  "SR:C29-MG{PS:QM2A}I:Sp1-SP",
                "SR:C29-MG{PS:QM2B}I:Sp1-SP",  "SR:C29-MG{PS:SQKM1A}I:Sp1-SP",  "SR:C30-MG{PS:BT1A}I:Sp1-SP",  "SR:C30-MG{PS:BT1A}I:Sp2-SP",
                "SR:C30-MG{PS:CH1A}I:Sp1-SP",  "SR:C30-MG{PS:CH1A}I:Sp2-SP",  "SR:C30-MG{PS:CH2A}I:Sp1-SP",  "SR:C30-MG{PS:CH2A}I:Sp2-SP",
                "SR:C30-MG{PS:CL1B}I:Sp1-SP",  "SR:C30-MG{PS:CL1B}I:Sp2-SP",  "SR:C30-MG{PS:CL2B}I:Sp1-SP",  "SR:C30-MG{PS:CL2B}I:Sp2-SP",
                "SR:C30-MG{PS:CM1A}I:Sp1-SP",  "SR:C30-MG{PS:CM1A}I:Sp2-SP",  "SR:C30-MG{PS:CM1B}I:Sp1-SP",  "SR:C30-MG{PS:CM1B}I:Sp2-SP",
                "SR:C30-MG{PS:QH1A}I:Sp1-SP",  "SR:C30-MG{PS:QH2A}I:Sp1-SP",  "SR:C30-MG{PS:QH3A}I:Sp1-SP",  "SR:C30-MG{PS:QL1B}I:Sp1-SP",
                "SR:C30-MG{PS:QL2B}I:Sp1-SP",  "SR:C30-MG{PS:QL3B}I:Sp1-SP",  "SR:C30-MG{PS:QM1A}I:Sp1-SP",  "SR:C30-MG{PS:QM1B}I:Sp1-SP",
                "SR:C30-MG{PS:QM2A}I:Sp1-SP",  "SR:C30-MG{PS:QM2B}I:Sp1-SP",  "SR:C30-MG{PS:SH1-P2}I:Sp1-SP",  "SR:C30-MG{PS:SH3-P2}I:Sp1-SP",
                "SR:C30-MG{PS:SQKH1A}I:Sp1-SP"]
        pvs0 =['SR:C01-MG{PS:SM1A-P2}I:Sp1-SP', 'SR:C02-MG{PS:SM1B-P2}I:Sp1-SP',
               'SR:C02-MG{PS:SM2B-P2}I:Sp1-SP', 'SR:C07-MG{PS:SM1A-P3}I:Sp1-SP',
               'SR:C08-MG{PS:SM1B-P3}I:Sp1-SP', 'SR:C08-MG{PS:SM2B-P3}I:Sp1-SP',
               'SR:C13-MG{PS:SM1A-P4}I:Sp1-SP', 'SR:C14-MG{PS:SM1B-P4}I:Sp1-SP',
               'SR:C14-MG{PS:SM2B-P4}I:Sp1-SP', 'SR:C19-MG{PS:SM1A-P5}I:Sp1-SP',
               'SR:C20-MG{PS:SM1B-P5}I:Sp1-SP', 'SR:C20-MG{PS:SM2B-P5}I:Sp1-SP',
               'SR:C25-MG{PS:SM1A-P1}I:Sp1-SP', 'SR:C26-MG{PS:SM1B-P1}I:Sp1-SP',
               'SR:C26-MG{PS:SM2B-P1}I:Sp1-SP']
        
        with self.assertRaises(KeyError) as context:
            updateconfig(self.conn, self.collection, name, pvlist={"name": pvs0})
        self.assertEqual(context.exception.message, 'Cannot find key ("names") for pv names.')
        
        self.assertTrue(updateconfig(self.conn, self.collection, name, pvlist={"names": pvs}))
        res3 = retrieveconfig(self.conn, self.collection, name, withpvs=True)
        self.assertEqual(res3[0]["status"], "active")
        self.assertNotEqual(res1[0]["updated_on"], res2[0]["updated_on"])
        self.assertEqual(res3[0]["created_on"], res0[0]["created_on"])
        self.assertEqual(res3[0]["pvlist"]["names"], pvs)
        with self.assertRaises(RuntimeError) as context:
            updateconfig(self.conn, self.collection, name, pvlist={"names": pvs0})
        self.assertEqual(context.exception.message, "PV collection list exists already, and should not be changed.")