def localInitialize(self): """ Will perform all initialization specific to this Sampler. For instance, creating an empty container to hold the identified surface points, error checking the optionally provided solution export and other preset values, and initializing the limit surface Post-Processor used by this sampler. @ In, None @ Out, None """ if len(self.hybridStrategyToApply.keys()) > 0: hybridlistoflist = [] for cnt, preckey in enumerate(self.hybridStrategyToApply.keys()): hybridsampler = self.hybridStrategyToApply[preckey] hybridlistoflist.append([]) hybridsampler.initialize() self.hybridNumberSamplers *= hybridsampler.limit while hybridsampler.amIreadyToProvideAnInput(): hybridsampler.counter +=1 hybridsampler.localGenerateInput(None,None) hybridsampler.inputInfo['prefix'] = hybridsampler.counter hybridlistoflist[cnt].append(copy.deepcopy(hybridsampler.inputInfo)) if self.hybridNumberSamplers > 0: self.raiseAMessage('Number of Hybrid Samples are ' + str(self.hybridNumberSamplers) + '!') hybridNumber = self.hybridNumberSamplers combinations = list(itertools.product(*hybridlistoflist)) else: hybridNumber = 1 self.TreeInfo = {} for precSample in range(hybridNumber): elm = ETS.HierarchicalNode(self.messageHandler,self.name + '_' + str(precSample+1)) elm.add('name', self.name + '_'+ str(precSample+1)) elm.add('startTime', str(0.0)) # Initialize the endTime to be equal to the start one... # It will modified at the end of each branch elm.add('endTime', str(0.0)) elm.add('runEnded',False) elm.add('running',True) elm.add('queue',False) # if preconditioned DET, add the sampled from hybridsampler samplers if self.hybridNumberSamplers > 0: elm.add('hybridsamplerCoordinate', combinations[precSample]) for point in combinations[precSample]: for epistVar, val in point['SampledVars'].items(): self.epistemicVariables[epistVar][elm.get('name')] = val # The dictionary branchedLevel is stored in the xml tree too. That's because # the advancement of the thresholds must follow the tree structure elm.add('branchedLevel', self.branchedLevel[0]) # Here it is stored all the info regarding the DET => we create the info for all the # branchings and we store them self.TreeInfo[self.name + '_' + str(precSample+1)] = ETS.HierarchicalTree(self.messageHandler,elm) for key in self.branchProbabilities.keys(): #kk = self.toBeSampled.values().index(key) #self.branchValues[key] = [self.distDict[self.toBeSampled.keys()[self.toBeSampled.values().index(key)]].ppf(float(self.branchProbabilities[key][index])) for index in range(len(self.branchProbabilities[key]))] self.branchValues[key] = [self.distDict[key].ppf(float(self.branchProbabilities[key][index])) for index in range(len(self.branchProbabilities[key]))] for key in self.branchValues.keys(): #kk = self.toBeSampled.values().index(key) #self.branchProbabilities[key] = [self.distDict[self.toBeSampled.keys()[self.toBeSampled.values().index(key)]].cdf(float(self.branchValues[key][index])) for index in range(len(self.branchValues[key]))] self.branchProbabilities[key] = [self.distDict[key].cdf(float(self.branchValues[key][index])) for index in range(len(self.branchValues[key]))] self.limit = sys.maxsize
if updateResults: results["fail"] += 1 return False else: if updateResults: results["pass"] += 1 return True ############## # Node Tests # ############## # TODO not complete! #test equivalency (eq, neq, hash) ## test all same are same a = TS.HierarchicalNode(mh,'rightTag',valuesIn={'attrib1':1,'attrib2':'2'},text='sampleText') b = TS.HierarchicalNode(mh,'rightTag',valuesIn={'attrib1':1,'attrib2':'2'},text='sampleText') checkSame('Equivalency of nodes ==:',a==b,True) checkSame('Equivalency of nodes !=:',a!=b,False) ## test different tag b = TS.HierarchicalNode(mh,'diffTag',valuesIn={'attrib1':1,'attrib2':'2'},text='sampleText') checkSame('Inequivalent tag ==:',a==b,False) checkSame('Inequivalent tag !=:',a!=b,True) ## test different attribute name b = TS.HierarchicalNode(mh,'rightTag',valuesIn={'attrib3':1,'attrib2':'2'},text='sampleText') checkSame('Inequivalent value name ==:',a==b,False) checkSame('Inequivalent value name !=:',a!=b,True) ## test different attribute value
def localGenerateInput(self, model, myInput): """ Function to select the next most informative point for refining the limit surface search. After this method is called, the self.inputInfo should be ready to be sent to the model @ In, model, model instance, an instance of a model @ In, myInput, list, a list of the original needed inputs for the model (e.g. list of files, etc.) @ Out, None """ if self.startAdaptive == True and self.adaptiveReady == True: LimitSurfaceSearch.localGenerateInput(self, model, myInput) #the adaptive sampler created the next point sampled vars #find the closest branch if self.hybridDETstrategy is not None: closestBranch, cdfValues, treer = self._checkClosestBranch() else: closestBranch, cdfValues = self._checkClosestBranch() if closestBranch is None: self.raiseADebug( 'An usable branch for next candidate has not been found => create a parallel branch!' ) # add pbthresholds in the grid investigatedPoint = {} for key, value in cdfValues.items(): try: ind = utils.first( np.atleast_1d( np.asarray(self.branchProbabilities[key]) <= value ).nonzero())[-1] except (IndexError, ValueError): ind = 0 if value not in self.branchProbabilities[key]: self.branchProbabilities[key].insert(ind, value) self.branchValues[key].insert( ind, self.distDict[key].ppf(value)) investigatedPoint[key] = value # collect investigated point self.investigatedPoints.append(investigatedPoint) if closestBranch: info = self._retrieveBranchInfo(closestBranch) self._constructEndInfoFromBranch(model, myInput, info, cdfValues) else: # create a new tree, since there are no branches that are close enough to the adaptive request elm = ETS.HierarchicalNode( self.messageHandler, self.name + '_' + str(len(self.TreeInfo.keys()) + 1)) elm.add('name', self.name + '_' + str(len(self.TreeInfo.keys()) + 1)) elm.add('startTime', 0.0) # Initialize the endTime to be equal to the start one... # It will modified at the end of each branch elm.add('endTime', 0.0) elm.add('runEnded', False) elm.add('running', True) elm.add('queue', False) elm.add('completedHistory', False) branchedLevel = {} for key, value in cdfValues.items(): branchedLevel[key] = utils.first( np.atleast_1d( np.asarray(self.branchProbabilities[key]) == value).nonzero())[-1] # The dictionary branchedLevel is stored in the xml tree too. That's because # the advancement of the thresholds must follow the tree structure elm.add('branchedLevel', branchedLevel) if self.hybridDETstrategy is not None and not self.foundEpistemicTree: # adaptive hybrid DET and not found a tree in the epistemic space # take the first tree and modify the hybridsamplerCoordinate hybridSampled = copy.deepcopy( utils.first(self.TreeInfo.values()).getrootnode().get( 'hybridsamplerCoordinate')) for hybridStrategy in hybridSampled: for key in self.epistemicVariables.keys(): if key in hybridStrategy['SampledVars'].keys(): self.raiseADebug("epistemic var " + str(key) + " value = " + str(self.values[key])) hybridStrategy['SampledVars'][key] = copy.copy( self.values[key]) hybridStrategy['SampledVarsPb'][ key] = self.distDict[key].pdf( self.values[key]) hybridStrategy['prefix'] = len( self.TreeInfo.values()) + 1 # TODO: find a strategy to recompute the probability weight here (for now == PointProbability) hybridStrategy['PointProbability'] = reduce( mul, self.inputInfo['SampledVarsPb'].values()) hybridStrategy['ProbabilityWeight'] = reduce( mul, self.inputInfo['SampledVarsPb'].values()) elm.add('hybridsamplerCoordinate', hybridSampled) self.inputInfo.update({ 'ProbabilityWeight-' + key.strip(): value for key, value in self.inputInfo['SampledVarsPb'].items() }) # Here it is stored all the info regarding the DET => we create the info for all the branchings and we store them self.TreeInfo[self.name + '_' + str(len(self.TreeInfo.keys()) + 1)] = ETS.HierarchicalTree( self.messageHandler, elm) self._createRunningQueueBeginOne( self.TreeInfo[self.name + '_' + str(len(self.TreeInfo.keys()))], branchedLevel, model, myInput) return DynamicEventTree.localGenerateInput(self, model, myInput)
def _constructEndInfoFromBranch(self, model, myInput, info, cdfValues): """ Method to construct the end information from the 'info' inputted @ In, model, Models object, the model that is used to explore the input space (e.g. a code, like RELAP-7) @ In, myInput, list, list of inputs for the Models object (passed through the Steps XML block) @ In, info, dict, dictionary of information at the end of a branch (information collected by the method _retrieveBranchInfo) @ In, cdfValues, dict, dictionary of CDF thresholds reached by the branch that just ended. @ Out, None """ endInfo = info['parentNode'].get('endInfo') del self.inputInfo self.counter += 1 self.branchCountOnLevel = info['actualBranchOnLevel'] + 1 # Get Parent node name => the branch name is creating appending to this name a comma and self.branchCountOnLevel counter rname = info['parentNode'].get('name') + '-' + str( self.branchCountOnLevel) info['parentNode'].add('completedHistory', False) self.raiseADebug(str(rname)) bcnt = self.branchCountOnLevel while info['parentNode'].isAnActualBranch(rname): bcnt += 1 rname = info['parentNode'].get('name') + '-' + str(bcnt) # create a subgroup that will be appended to the parent element in the xml tree structure subGroup = ETS.HierarchicalNode(self.messageHandler, rname) subGroup.add('parent', info['parentNode'].get('name')) subGroup.add('name', rname) self.raiseADebug('cond pb = ' + str(info['parentNode'].get('conditionalPbr'))) condPbC = float(info['parentNode'].get('conditionalPbr')) # Loop over branchChangedParams (events) and start storing information, # such as conditional pb, variable values, into the xml tree object branchChangedParamValue = [] branchChangedParamPb = [] branchParams = [] if endInfo: for key in endInfo['branchChangedParams'].keys(): branchParams.append(key) branchChangedParamPb.append(endInfo['branchChangedParams'][key] ['associatedProbability'][0]) branchChangedParamValue.append( endInfo['branchChangedParams'][key]['oldValue'][0]) subGroup.add('branchChangedParam', branchParams) subGroup.add('branchChangedParamValue', branchChangedParamValue) subGroup.add('branchChangedParamPb', branchChangedParamPb) else: pass # add conditional probability subGroup.add('conditionalPbr', condPbC) # add initiator distribution info, start time, etc. subGroup.add('startTime', info['parentNode'].get('endTime')) # initialize the endTime to be equal to the start one... It will modified at the end of this branch subGroup.add('endTime', info['parentNode'].get('endTime')) # add the branchedLevel dictionary to the subgroup # branch calculation info... running, queue, etc are set here subGroup.add('runEnded', False) subGroup.add('running', False) subGroup.add('queue', True) subGroup.add('completedHistory', False) # Append the new branch (subgroup) info to the parentNode in the tree object info['parentNode'].appendBranch(subGroup) # Fill the values dictionary that will be passed into the model in order to create an input # In this dictionary the info for changing the original input is stored self.inputInfo = { 'prefix': rname, 'endTimeStep': info['parentNode'].get('actualEndTimeStep'), 'branchChangedParam': subGroup.get('branchChangedParam'), 'branchChangedParamValue': subGroup.get('branchChangedParamValue'), 'conditionalPb': subGroup.get('conditionalPbr'), 'startTime': info['parentNode'].get('endTime'), 'RAVEN_parentID': subGroup.get('parent'), 'RAVEN_isEnding': True } # add the newer branch name to the map self.rootToJob[rname] = self.rootToJob[subGroup.get('parent')] # check if it is a preconditioned DET sampling, if so add the relative information # it exists only in case an hybridDET strategy is activated precSampled = info['parentNode'].get('hybridsamplerCoordinate') if precSampled: self.inputInfo['hybridsamplerCoordinate'] = copy.deepcopy( precSampled) subGroup.add('hybridsamplerCoordinate', copy.copy(precSampled)) # The probability Thresholds are stored here in the cdfValues dictionary... We are sure that they are whitin the ones defined in the grid # check is not needed self.inputInfo['initiatorDistribution'] = [ self.toBeSampled[key] for key in cdfValues.keys() ] self.inputInfo['PbThreshold'] = list(cdfValues.values()) self.inputInfo['ValueThreshold'] = [ self.distDict[key].ppf(value) for key, value in cdfValues.items() ] self.inputInfo['SampledVars'] = {} self.inputInfo['SampledVarsPb'] = {} for varname in self.standardDETvariables: self.inputInfo['SampledVars'][varname] = self.distDict[ varname].ppf(cdfValues[varname]) self.inputInfo['SampledVarsPb'][varname] = cdfValues[varname] # constant variables self._constantVariables() if precSampled: for precSample in precSampled: self.inputInfo['SampledVars'].update(precSample['SampledVars']) self.inputInfo['SampledVarsPb'].update( precSample['SampledVarsPb']) self.inputInfo['PointProbability'] = reduce( mul, self.inputInfo['SampledVarsPb'].values()) * subGroup.get( 'conditionalPbr') self.inputInfo['ProbabilityWeight'] = self.inputInfo[ 'PointProbability'] self.inputInfo.update({ 'ProbabilityWeight-' + key.strip(): value for key, value in self.inputInfo['SampledVarsPb'].items() }) # add additional edits if needed model.getAdditionalInputEdits(self.inputInfo) # Add the new input path into the RunQueue system newInputs = {'args': [str(self.type)], 'kwargs': dict(self.inputInfo)} self.RunQueue['queue'].append(newInputs) self.RunQueue['identifiers'].append(self.inputInfo['prefix']) for key, value in self.inputInfo.items(): subGroup.add(key, copy.copy(value)) if endInfo: subGroup.add('endInfo', copy.deepcopy(endInfo))
def _createRunningQueueBranch(self,model,myInput,forceEvent=False): """ Method to generate the running internal queue right after a branch occurred It generates the the information to insatiate the branches' continuation of the Deterministic Dynamic Event Tree @ In, model, Models object, the model that is used to explore the input space (e.g. a code, like RELAP-7) @ In, myInput, list, list of inputs for the Models object (passed through the Steps XML block) @ In, forceEvent, bool, if True the events are forced to happen (basically, the "unchanged event" is not created at all) @ Out, None """ # The first DET calculation branch has already been run' # Start the manipulation: # Pop out the last endInfo information and the branchedLevel branchedLevelParent = self.branchedLevel.pop(0) endInfo = self.endInfo.pop(0) self.branchCountOnLevel = 0 #? # n_branches = number of branches need to be run nBranches = endInfo['n_branches'] # Check if the distribution that just triggered hitted the last probability threshold . # In case we create a number of branches = endInfo['n_branches'] - 1 => the branch in # which the event did not occur is not going to be tracked if branchedLevelParent[endInfo['branchDist']] >= len(self.branchProbabilities[endInfo['branchDist']]): self.raiseADebug('Branch ' + endInfo['parentNode'].get('name') + ' hit last Threshold for distribution ' + endInfo['branchDist']) self.raiseADebug('Branch ' + endInfo['parentNode'].get('name') + ' is dead end.') self.branchCountOnLevel = 1 nBranches -= 1 else: if forceEvent == True: self.branchCountOnLevel = 1 nBranches -= 1 # Loop over the branches for which the inputs must be created for _ in range(nBranches): del self.inputInfo self.counter += 1 self.branchCountOnLevel += 1 branchedLevel = copy.deepcopy(branchedLevelParent) # Get Parent node name => the branch name is creating appending to this name a comma and self.branchCountOnLevel counter rname = endInfo['parentNode'].get('name') + '-' + str(self.branchCountOnLevel) # create a subgroup that will be appended to the parent element in the xml tree structure subGroup = ETS.HierarchicalNode(self.messageHandler,rname.encode()) subGroup.add('parent', endInfo['parentNode'].get('name')) subGroup.add('name', rname) subGroup.add('completedHistory', False) # condPbUn = conditional probability event not occur # condPbC = conditional probability event/s occur/s condPbUn = 0.0 condPbC = 0.0 # Loop over branchChangedParams (events) and start storing information, # such as conditional pb, variable values, into the xml tree object branchChangedParamValue = [] branchChangedParamPb = [] branchParams = [] #subGroup.add('branchChangedParam',endInfo['branchChangedParams'].keys()) for key in endInfo['branchChangedParams'].keys(): #subGroup.add('branchChangedParam',key) branchParams.append(key) if self.branchCountOnLevel != 1: branchChangedParamValue.append(endInfo['branchChangedParams'][key]['actualValue'][self.branchCountOnLevel-2]) branchChangedParamPb.append(endInfo['branchChangedParams'][key]['associatedProbability'][self.branchCountOnLevel-2]) #subGroup.add('branchChangedParamValue',endInfo['branchChangedParams'][key]['actualValue'][self.branchCountOnLevel-2]) #subGroup.add('branchChangedParamPb',endInfo['branchChangedParams'][key]['associatedProbability'][self.branchCountOnLevel-2]) #condPbC.append(endInfo['branchChangedParams'][key]['changedConditionalPb'][self.branchCountOnLevel-2]) condPbC = condPbC + endInfo['branchChangedParams'][key]['changedConditionalPb'][self.branchCountOnLevel-2] subGroup.add('happenedEvent',True) else: subGroup.add('happenedEvent',endInfo['parentNode'].get('happenedEvent')) branchChangedParamValue.append(endInfo['branchChangedParams'][key]['oldValue']) branchChangedParamPb.append(endInfo['branchChangedParams'][key]['unchangedPb']) #subGroup.add('branchChangedParamValue',endInfo['branchChangedParams'][key]['oldValue']) #subGroup.add('branchChangedParamPb',endInfo['branchChangedParams'][key]['unchangedPb']) #condPbUn.append(endInfo['branchChangedParams'][key]['unchangedConditionalPb']) condPbUn = condPbUn + endInfo['branchChangedParams'][key]['unchangedConditionalPb'] subGroup.add('branchChangedParam',branchParams) # add conditional probability if self.branchCountOnLevel != 1: subGroup.add('conditionalPbr',condPbC) subGroup.add('branchChangedParamValue',branchChangedParamValue) subGroup.add('branchChangedParamPb',branchChangedParamPb) else: subGroup.add('conditionalPbr',condPbUn) subGroup.add('branchChangedParamValue',branchChangedParamValue) subGroup.add('branchChangedParamPb',branchChangedParamPb) # add initiator distribution info, start time, etc. subGroup.add('initiatorDistribution',self.toBeSampled[endInfo['branchDist']]) subGroup.add('startTime', endInfo['parentNode'].get('endTime')) # initialize the endTime to be equal to the start one... It will modified at the end of this branch subGroup.add('endTime', endInfo['parentNode'].get('endTime')) # add the branchedLevel dictionary to the subgroup if self.branchCountOnLevel != 1: branchedLevel[endInfo['branchDist']] = branchedLevel[endInfo['branchDist']] - 1 # branch calculation info... running, queue, etc are set here subGroup.add('runEnded',False) subGroup.add('running',False) subGroup.add('queue',True) # subGroup.set('restartFileRoot',endInfo['restartRoot']) # Append the new branch (subgroup) info to the parentNode in the tree object endInfo['parentNode'].appendBranch(subGroup) # Fill the values dictionary that will be passed into the model in order to create an input # In this dictionary the info for changing the original input is stored self.inputInfo = {'prefix':rname.encode(),'endTimeStep':endInfo['endTimeStep'], 'branchChangedParam':subGroup.get('branchChangedParam'), 'branchChangedParamValue':subGroup.get('branchChangedParamValue'), 'conditionalPb':subGroup.get('conditionalPbr'), 'startTime':endInfo['parentNode'].get('endTime'), 'parentID':subGroup.get('parent')} self.inputInfo['happenedEvent'] = subGroup.get('happenedEvent') # add additional edits if needed model.getAdditionalInputEdits(self.inputInfo) # add the newer branch name to the map self.rootToJob[rname] = self.rootToJob[subGroup.get('parent')] # check if it is a preconditioned DET sampling, if so add the relative information precSampled = endInfo['parentNode'].get('hybridsamplerCoordinate') if precSampled: self.inputInfo['hybridsamplerCoordinate'] = copy.deepcopy(precSampled) subGroup.add('hybridsamplerCoordinate', precSampled) # Check if the distribution that just triggered hitted the last probability threshold . # In this case there is not a probability threshold that needs to be added in the input # for this particular distribution if not (branchedLevel[endInfo['branchDist']] >= len(self.branchProbabilities[endInfo['branchDist']])): self.inputInfo['initiatorDistribution'] = [self.toBeSampled[endInfo['branchDist']]] self.inputInfo['PbThreshold' ] = [self.branchProbabilities[endInfo['branchDist']][branchedLevel[endInfo['branchDist']]]] self.inputInfo['ValueThreshold' ] = [self.branchValues[endInfo['branchDist']][branchedLevel[endInfo['branchDist']]]] # For the other distributions, we put the unbranched thresholds # Before adding these thresholds, check if the keyword 'initiatorDistribution' is present... # (In the case the previous if statement is true, this keyword is not present yet # Add it otherwise if not ('initiatorDistribution' in self.inputInfo.keys()): self.inputInfo['initiatorDistribution' ] = [] self.inputInfo['PbThreshold' ] = [] self.inputInfo['ValueThreshold' ] = [] # Add the unbranched thresholds for key in self.branchProbabilities.keys(): if not (key in self.toBeSampled[endInfo['branchDist']]) and (branchedLevel[key] < len(self.branchProbabilities[key])): self.inputInfo['initiatorDistribution'].append(self.toBeSampled[key.encode()]) for key in self.branchProbabilities.keys(): if not (key in self.toBeSampled[endInfo['branchDist']]) and (branchedLevel[key] < len(self.branchProbabilities[key])): self.inputInfo['PbThreshold' ].append(self.branchProbabilities[key][branchedLevel[key]]) self.inputInfo['ValueThreshold'].append(self.branchValues[key][branchedLevel[key]]) self.inputInfo['SampledVars'] = {} self.inputInfo['SampledVarsPb'] = {} for varname in self.standardDETvariables: self.inputInfo['SampledVars'][varname] = self.branchValues[varname][branchedLevel[varname]] self.inputInfo['SampledVarsPb'][varname] = self.branchProbabilities[varname][branchedLevel[varname]] #self.inputInfo['SampledVars'][varname] = self.branchValues[self.toBeSampled[varname]][branchedLevel[self.toBeSampled[varname]]] #self.inputInfo['SampledVarsPb'][varname] = self.branchProbabilities[self.toBeSampled[varname]][branchedLevel[self.toBeSampled[varname]]] self._constantVariables() if precSampled: for precSample in precSampled: self.inputInfo['SampledVars' ].update(precSample['SampledVars']) self.inputInfo['SampledVarsPb'].update(precSample['SampledVarsPb']) self.inputInfo['PointProbability' ] = reduce(mul, self.inputInfo['SampledVarsPb'].values())*subGroup.get('conditionalPbr') self.inputInfo['ProbabilityWeight'] = self.inputInfo['PointProbability' ] # Call the model function "createNewInput" with the "values" dictionary just filled. # Add the new input path into the RunQueue system self.RunQueue['queue'].append(model.createNewInput(myInput,self.type,**self.inputInfo)) self.RunQueue['identifiers'].append(self.inputInfo['prefix']) for key,value in self.inputInfo.items(): subGroup.add(key,value) popped = endInfo.pop('parentNode') subGroup.add('endInfo',copy.deepcopy(endInfo)) endInfo['parentNode'] = popped del branchedLevel