def run(self): super(Lims, self).runSimulate() # Do the work # post processing properties = {} tokens = self.getTokenList().getTokensByOwnerAndSpec("ap", self, properties, lockedState=True) if tokens == None or len(tokens) == 0: utils.logTrace("No Assay Plate barcode") tokenApInProcess = tokens[0] barcodeAP = tokenApInProcess.getProperty("barcodeAP") properties = {} tokens = self.getTokenList().getTokensByOwnerAndSpec("sp", None, properties, lockedState=False) numreq = 3 for token in tokens: color = token.getProperty("color") if color == "free": token.setProperty("barcodeAP", barcodeAP) token.setProperty("prevTransition", "lims") token.setProperty("color", "reserved") numreq -= 1 if numreq <= 0: break # Complete transition super(Lims, self).complete() utils.log("Exit " + self.getName() + " " + repr(os.getpid()) + " " + threading.currentThread().getName()) exit()
def IsEnabled(self, tokenList): # First get common properties across required tokens commonValuesByTokenName = {} for transitionProperty in self.properties.keys(): commonValuesByTokenName[transitionProperty] = {} for reqTokenName, tokenSpec in self.requiredTokensByState.items(): tokensAvailable = 0 numRequired = tokenSpec[1] if reqTokenName in tokenList.list: tokens = tokenList.getTokensByOwnerAndSpec( reqTokenName, transitionOwnerObject=None, properties=tokenSpec[0], lockedState=False ) for token in tokens: tokensAvailable += 1 for transitionPropertyName in self.properties.keys(): if transitionPropertyName in token.getProperties(): if not token.getName() in commonValuesByTokenName[transitionPropertyName]: commonValuesByTokenName[transitionPropertyName][token.getName()] = [] commonValuesByTokenName[transitionPropertyName][token.getName()].append( token.getProperty(transitionPropertyName) ) if tokensAvailable < numRequired: utils.log("Cannot run " + self.getName() + " because not enough " + reqTokenName + "'s available.'") return False, {} else: utils.log("Cannot run " + self.getName() + " because token " + reqTokenName + " not available.") return False, {} # So commonValuesByTokenName is owned by the transitionItem and manages the properties that it cares about. # For each one of these properties, it contains a list of all of its required tokens and the values of that property # across those tokens. The idea is that the transition can specify that for a given property if the tokens available # contain that property then their values must match. For example, if the "dosing" transition requires an "assay plate" # and a "source plate" token then it may require that the common assay plate barcode be the same in both tokens for # those tokens to be acquired by the instance of the transition. intersections = {} intersect = [] for transitionPropertyName in commonValuesByTokenName.keys(): prev = [] req = ["any"] if transitionPropertyName in self.properties and self.properties[transitionPropertyName] != None: req = self.properties[transitionPropertyName] if transitionPropertyName == "prevTransition" and "prevTransition" in self.properties: prev = prev + self.properties["prevTransition"] if "any" in req: intersections[transitionPropertyName] = intersect for tokenName in commonValuesByTokenName[transitionPropertyName].keys(): current = commonValuesByTokenName[transitionPropertyName][tokenName] if len(prev) > 0 and len(current) > 0: intersect = [val for val in prev if val in current] if len(intersect) == 0: utils.log( "Cannot run " + self.getName() + " because no matching on " + transitionPropertyName + " for " + tokenName ) return False, {} prev = intersect else: prev = current intersect = current intersections[transitionPropertyName] = intersect for tokenName in intersections.keys(): valueList = intersections[tokenName] # We may have found more than one set of common property values. Choose one set only. intersections[tokenName] = [valueList[0]] # Choose single member of overlap utils.log("Candidate " + self.getName() + " intersection " + repr(intersections)) return True, intersections