def pickbestidv(self, list_idv, list_fit, lo_sigma_fit, up_sigma_fit): list_phis_good = [] mean_fit = sum(list_fit)/len(list_fit) std_fit = np.std(list_fit) fit_thres_lo = mean_fit + (lo_sigma_fit * std_fit) fit_thres_hi = mean_fit + (up_sigma_fit * std_fit) for i_idv in range(len(list_idv)): if list_fit[i_idv] > fit_thres_lo and list_fit[i_idv] <= fit_thres_hi: list_phis_good.append(list_idv[i_idv]) #find centroid phase for phis_good from mod_util import util_handler uth = util_handler() flex_phi_bar, dummy = uth.calcphibar(list_phis_good) return flex_phi_bar, mean_fit, std_fit, len(list_phis_good)
def calc_stats(self, miller_arrays, indices_selected, phi_selected, fom_selected, iparams): map_coeff = self.setup_map_coeff(miller_arrays, indices_selected, phi_selected, fom_selected) skew = self.calcskew(map_coeff, iparams) fp_selected = flex.double([miller_arrays[0].data()[inds] for inds in indices_selected]) phic_selected = flex.double([miller_arrays[4].data()[inds] for inds in indices_selected]) mpe_phi = 0 mapcc_phi = 0 if iparams.hklrefin is not None and \ np.sum(phic_selected) > 0: from mod_util import util_handler uth = util_handler() mapcc_phi, mpe_phi = uth.calcphicc(fp_selected, [1]*len(fom_selected), fom_selected, phic_selected, phi_selected, True) return skew, mapcc_phi, mpe_phi
def run_optimize(self, micro_cycle_no, stack_no, miller_arrays, indices_selected, cdf_set, iparams): #start ga from mod_ga import ga_handler gah = ga_handler() from mod_util import util_handler uth = util_handler() list_phis_intcycle = [] list_fit_intcycle = [] #initial fist population and calculate their fitness ga_idv_length = len(indices_selected) cur_pop=gah.initialse(iparams.ga_params.pop_size, ga_idv_length, cdf_set, self.phi_for_hl) cur_fit=[0]*len(cur_pop) #setup new fp, phic (if given), fom, and new fom fp_selected = flex.double([miller_arrays[0].data()[inds] for inds in indices_selected]) phib_selected = flex.double([miller_arrays[1].data()[inds] for inds in indices_selected]) fom_selected = flex.double([miller_arrays[2].data()[inds] for inds in indices_selected]) fom_selected_new = fom_selected + 0.2 #calculate initial mapcc and mpe skew, mapcc, mpe = self.calc_stats(miller_arrays, indices_selected, phib_selected, fom_selected, iparams) txt_prn_out = "Starting stack %2.0f: microcycle %2.0f (initial skew=%6.2f, mapcc=%6.2f, mpe=%6.2f)\n"%(\ stack_no+1, micro_cycle_no+1, skew, mapcc, mpe*180/math.pi) print txt_prn_out txt_pop_hist_out="" for i_idv in range(len(cur_pop)): map_coeff = self.setup_map_coeff(miller_arrays, indices_selected, flex.double(cur_pop[i_idv]), fom_selected_new) cur_fit[i_idv] = self.calcskew(map_coeff, iparams) #collect the first population list_phis_intcycle.append(cur_pop[i_idv]) list_fit_intcycle.append(cur_fit[i_idv]) txt_prn_tmp = 'gen'.center(5)+'<skew>'.center(7)+'std_skew'.center(8)+'n_accidv'.center(10)+ \ 'skew'.center(6)+'mapcc'.center(7)+'mpe'.center(5)+'mapccp'.center(7)+'mpep'.center(6)+'time_spent (min)'.center(16)+'\n' print txt_prn_tmp txt_prn_out += txt_prn_tmp #Set up population map #[[7,1,5], #[2,3,0], #[4,6,9]] map_width=int(math.sqrt(iparams.ga_params.pop_size)) map_1D=random.sample(range(iparams.ga_params.pop_size), iparams.ga_params.pop_size) map_2D=[] for i_width in range(map_width): map_2D.append(map_1D[int(map_width*i_width):int(map_width*(i_width+1))]) map_visit_order=random.sample(range(iparams.ga_params.pop_size), iparams.ga_params.pop_size) #start a generation conv_gen = iparams.ga_params.max_gen for i_gen in range(iparams.ga_params.max_gen): time_gen_start=datetime.now() #calculate crossover rate for this generation ga_ratio_cross=iparams.ga_params.crossover_start_rate + \ (math.pow(i_gen/iparams.ga_params.max_gen, iparams.ga_params.crossover_slope) * \ (iparams.ga_params.crossover_end_rate-iparams.ga_params.crossover_start_rate)) num_point_cross=int(round(ga_ratio_cross * ga_idv_length)) for i_idv in range(len(map_visit_order)): mom_x=int(math.fmod(map_visit_order[i_idv], map_width)) mom_y=int(math.floor(map_visit_order[i_idv]/map_width)) mom_id=map_2D[mom_x][mom_y] mom=cur_pop[mom_id] mom_fit=cur_fit[mom_id] #draw an xmap around mom and grab the idv_id stored in map_2D mate_candidate_id=[] xmap_width = (iparams.ga_params.xmap_radius * 2) + 1 for i_xmap_y in range(xmap_width): for i_xmap_x in range(xmap_width): i_xmap_tmp_x=mom_x+i_xmap_x-iparams.ga_params.xmap_radius i_xmap_tmp_y=mom_y+i_xmap_y-iparams.ga_params.xmap_radius if i_xmap_tmp_x >= xmap_width: i_xmap_tmp_x-= xmap_width if i_xmap_tmp_y >= xmap_width: i_xmap_tmp_y-= xmap_width if ~(map_2D[i_xmap_tmp_x][i_xmap_tmp_y]==mom_id): mate_candidate_id.append(map_2D[i_xmap_tmp_x][i_xmap_tmp_y]) mate_candiate_id_random_order=random.sample(range(len(mate_candidate_id)), iparams.ga_params.num_sel_mate) tmp_mate_fit_set=[] for i_mate in range(iparams.ga_params.num_sel_mate): tmp_mate_fit_set.append( [mate_candidate_id[mate_candiate_id_random_order[i_mate]], cur_fit[mate_candidate_id[mate_candiate_id_random_order[i_mate]]]]) tmp_mate_fit_sort=sorted(tmp_mate_fit_set, key=lambda fit: fit[1],reverse=True) dad_id=tmp_mate_fit_sort[0][0] dad=cur_pop[dad_id] #perform ga operator - perform under probability #otherwise keeps the mom if random.random() < iparams.ga_params.prob_of_cross: child1,child2,cross_template = gah.crossover(mom, dad, ga_ratio_cross) child1 = gah.mutation( child1, iparams.ga_params.prob_of_mut, iparams.ga_params.num_point_mut, cdf_set, self.phi_for_hl) child2 = gah.mutation( child2, iparams.ga_params.prob_of_mut, iparams.ga_params.num_point_mut, cdf_set, self.phi_for_hl) #recalculate fitness map_coeff = self.setup_map_coeff(miller_arrays, indices_selected, flex.double(child1), fom_selected_new) child1_fit = self.calcskew(map_coeff, iparams) map_coeff = self.setup_map_coeff(miller_arrays, indices_selected, flex.double(child2), fom_selected_new) child2_fit = self.calcskew(map_coeff, iparams) if child1_fit >= child2_fit: child_sel=child1[:] child_fit_sel=child1_fit else: child_sel=child2[:] child_fit_sel=child2_fit if child_fit_sel > cur_fit[mom_id]: cur_pop[mom_id]=child_sel[:] cur_fit[mom_id]=child_fit_sel ''' collect some stats ''' #1. record some stats time_gen_end=datetime.now() time_gen_spent=time_gen_end-time_gen_start #2. mapcc and mpe among population n_idv_pick=int(round(0.05*iparams.ga_params.pop_size)) mpe_idv_pick=[0]*n_idv_pick mapcc_idv_pick=[0]*n_idv_pick id_idv_pick=random.sample(xrange(iparams.ga_params.pop_size), n_idv_pick) for i in range(n_idv_pick): i_idv_pick = id_idv_pick[i] mpe_to_others = [0] * iparams.ga_params.pop_size mapcc_to_others = [0] * iparams.ga_params.pop_size for j in range(iparams.ga_params.pop_size): mapcc_to_others[j], mpe_to_others[j] = uth.calcphicc( fp_selected, fom_selected_new, fom_selected_new, cur_pop[i_idv_pick], cur_pop[j], True) mpe_idv_pick[i]=sum(mpe_to_others)/iparams.ga_params.pop_size mapcc_idv_pick[i]=sum(mapcc_to_others)/iparams.ga_params.pop_size mpe_avg_gen = sum(mpe_idv_pick)/len(mpe_idv_pick) mapcc_avg_gen = sum(mapcc_idv_pick)/len(mapcc_idv_pick) #3. collect the population in generation for i_idv in range(len(cur_pop)): list_phis_intcycle.append(cur_pop[i_idv]) list_fit_intcycle.append(cur_fit[i_idv]) #4. calculate averaged phis among available phis now flex_phis_intcycle, \ mean_fit_intcycle, \ std_fit_intcycle, \ num_good_idv_intcycle = self.pickbestidv( list_phis_intcycle, list_fit_intcycle, iparams.ga_params.skew_sigma_sel_lo, iparams.ga_params.skew_sigma_sel_hi) flex_phis_fit_intcycle, mapcc_phis_intcycle, mpe_phis_intcycle = self.calc_stats(\ miller_arrays, indices_selected, flex_phis_intcycle, fom_selected_new, iparams) txt_prn_tmp = '%2.0f %7.2f %8.2f %6.0f %8.2f %5.2f %6.2f %6.2f %6.2f %10.2f\n'%(i_gen+1, \ mean_fit_intcycle, std_fit_intcycle, num_good_idv_intcycle, flex_phis_fit_intcycle, \ mapcc_phis_intcycle, mpe_phis_intcycle*180/math.pi, \ mapcc_avg_gen, mpe_avg_gen*180/math.pi, time_gen_spent.seconds/60) print txt_prn_tmp txt_prn_out += txt_prn_tmp #check termination if mapcc_avg_gen >= 0.9: conv_gen = i_gen break txt_prn_out += 'Population converged at generation '+str(conv_gen+1)+'\n' #complete one internal cycle if iparams.flag_log_verbose_on: #for phis in list_phis_intcycle: # print phis """ file_name_pop_hist_out = iparams.project_name+'/'+iparams.run_name+"/log_pop_hist_step_"+str(stack_no+1)+"_intcycle_"+str(micro_cycle_no+1)+".log" output = open(file_name_pop_hist_out, 'w') output.write(list(list_phis_intcycle)) output.close() """ return flex_phis_intcycle, fom_selected_new, flex_phis_fit_intcycle, txt_prn_out