def make_RotamerTrialsMover( moveable_residues, sf, input_pose, pack_radius = None ): ''' Given a list of <moveable_residues>, get all additional residues within <pack_radius> Angstroms around them in <input_pose> and return a RotamerTrialsMover that will pack these residues If no <pack_radius> is given, then only residues in <moveable_residues> will be allowed to pack :param moveable_residues: list( Pose numbers ) :param sf: ScoreFunction :param input_pose: Pose :param pack_radius: int( or float( radius in Angstroms to pack around the <moveable_residues>. Uses nbr_atom to determine residues in proximity ) ) Default = None which means that only residues in <moveable_residues> get packed :return: RotamerTrialsMover ''' # imports from rosetta import standard_packer_task, RotamerTrialsMover # copy over the input_pose pose = input_pose.clone() # make the PackRotamersMover from the passed MoveMap # default of standard_packer_task is to set packing for residues to True task = standard_packer_task( pose ) task.or_include_current( True ) task.restrict_to_repacking() # if a pack_radius was not given, then everything gets packed. So the task does not need to be adjusted as the default option is packing True for all # otherwise, if a pack_radius was given, turn off repacking for residues outside the pack_radius if pack_radius is not None: # get all the protein residues within pack_radius of the moveable_residues # inclue_passed_res_nums means that the function will return a list of residues that includes all numbers in moveable_residues # I am adding them in myself for clarity, so this setting is set to off nearby_protein_residues = get_res_nums_within_radius( moveable_residues, pose, radius = pack_radius, include_passed_res_nums = False ) # create a list of residue numbers that can be packed # meaning, the moveable carbohydrate residues and the residues around them packable_residues = [ res_num for res_num in moveable_residues ] packable_residues.extend( nearby_protein_residues ) packable_residues = list( set( packable_residues ) ) # turn off packing for all residues that are NOT packable # i.e. for all residues in the pose, turn OFF packing if they are NOT in the packable_residues list [ task.nonconst_residue_task( res_num ).prevent_repacking() for res_num in range( 1, pose.n_residue() + 1 ) if res_num not in packable_residues ] # otherwise, only residues specified by moveable_residues should be allowed to be packed else: # turn off repacking for all residues in the pose that are NOT in moveable_residues # no pack_radius was given, so all residues not specified in moveable_residues should not be packed [ task.nonconst_residue_task( res_num ).prevent_repacking() for res_num in range( 1, pose.n_residue() + 1 ) if res_num not in moveable_residues ] # make the pack_rotamers_mover with the given ScoreFunction and created task pack_rotamers_mover = RotamerTrialsMover( sf, task ) return pack_rotamers_mover
def mutate_residue_chain(pose, mutant_position, mutant_aa, pack_radius = 0.0, pack_scorefxn = '' ): """ Replaces the residue at <mutant_position> in <pose> with <mutant_aa> and repack any residues within <pack_radius> Angstroms of the mutating residue's center (nbr_atom) using <pack_scorefxn> note: <mutant_aa> is the single letter name for the desired ResidueType example: mutate_residue(pose, 30, A) See also: Pose PackRotamersMover MutateResidue pose_from_sequence """ #### a MutateResidue Mover exists similar to this except it does not pack #### the area around the mutant residue (no pack_radius feature) #mutator = MutateResidue(mutant_position, mutant_aa) #mutator.apply(test_pose) #test_pose = Pose() #test_pose.assign( pose ) if pose.is_fullatom() == False: IOError( 'mutate_residue only works with fullatom poses' ) # create a standard scorefxn by default if not pack_scorefxn: pack_scorefxn = get_fa_scorefxn() # create_score_function('standard') task = standard_packer_task(pose) # the Vector1 of booleans (a specific object) is needed for specifying the # mutation, this demonstrates another more direct method of setting # PackerTask options for design aa_bool = rosetta.utility.vector1_bool() # PyRosetta uses several ways of tracking amino acids (ResidueTypes) # the numbers 1-20 correspond individually to the 20 proteogenic amino acids # aa_from_oneletter returns the integer representation of an amino acid # from its one letter code # convert mutant_aa to its integer representation mutant_aa = aa_from_oneletter_code(mutant_aa) # mutation is performed by using a PackerTask with only the mutant # amino acid available during design # to do this, construct a Vector1 of booleans indicating which amino acid # (by its numerical designation, see above) to allow for i in range(1, 21): # in Python, logical expression are evaluated with priority, thus the # line below appends to aa_bool the truth (True or False) of the # statement i == mutant_aa aa_bool.append( i == mutant_aa ) # modify the mutating residue's assignment in the PackerTask using the # Vector1 of booleans across the proteogenic amino acids # prevent residues from packing if they are in a different chain then the mutant task2=restrict_non_nbrs_from_repacking_chain(pose, mutant_position, task, pack_radius) task2.nonconst_residue_task(mutant_position ).restrict_absent_canonical_aas(aa_bool) # apply the mutation and pack nearby residues packer = PackRotamersMover(pack_scorefxn, task2) packer.apply(pose) return(pose)
pdb_chain = 'B', do_pack = False, do_min = False ) ) except: continue ########################### #### gradient pack/min #### ########################### min_pose = Pose() for ii in range( 1 ): working_pose = mutant_pose.clone() for jj in range( 1 ): # packing task = standard_packer_task( working_pose ) task.or_include_current( True ) task.restrict_to_repacking() rtm = RotamerTrialsMover( sf, task ) rtm.apply( working_pose ) # minimizing mm = MoveMap() mm.set_bb( True ) mm.set_chi( True ) min_mover = MinMover( movemap_in = mm, scorefxn_in = sf, min_type_in = "dfpmin_strong_wolfe", tolerance_in = 0.01, use_nb_list_in = True ) min_mover.max_iter( 2500 )
def main(): parser = argparse.ArgumentParser() parser.add_argument('pdb_filename', action="store", type=str) parser.add_argument('replicate_number', action="store", type=int) inputs = parser.parse_args() #takes name of pdb file without the extention pdb_file = inputs.pdb_filename prot_name = pdb_file.split('/')[-1].split('.')[0] #set up timer to figure out how long the code took to run t0 = time() fasta_file = pdb_file.replace('/structures/', '/fastas/').replace('.pdb', '.fasta') records = list(SeqIO.parse(fasta_file, 'fasta')) assert len(records) == 1 wt_seq = str(records[0].seq) # Initialize Rosetta. #init(extra_options='-mute basic -mute core') init(extra_options= '-mute basic -mute core -rebuild_disulf false -detect_disulf false') ######################## # Constants ######################## PACK_RADIUS = 12.0 #Amino acids AAs = ("A", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "V", "W", "Y") AAs_choice_dict = {} for aa in AAs: AAs_choice_dict[aa] = [other_aa for other_aa in AAs if other_aa != aa] #Number of mutations to accept max_accept_mut = 10 * len(wt_seq) #max_accept_mut = 2048 #Population size N = 1000 #Beta (temp term) beta = 1 #Fraction of the WT stability value to shoot for threshold_fraction = 0.5 ######################## ######################## #Prepare data headers data = ['Variant,Rosetta Score,"delta-delta-G",Probability,Generation\n'] #Load a clean pdb file initial_pose = pose_from_pdb(pdb_file) if '.clean' in pdb_file: pdb_file = ''.join(pdb_file.split('.clean')) #Set up ScoreFunction sf = get_fa_scorefxn() #Set up MoveMap. mm = MoveMap() mm.set_bb(True) mm.set_chi(True) #Pack and minimize initial pose to remove clashes. pre_pre_packing_score = sf(initial_pose) task = standard_packer_task(initial_pose) task.restrict_to_repacking() task.or_include_current(True) pack_rotamers_mover = RotamerTrialsMover(sf, task) pack_rotamers_mover.apply(initial_pose) min_mover = MinMover() min_mover.movemap(mm) min_mover.score_function(sf) min_mover.min_type('dfpmin_armijo_nonmonotone') min_mover.apply(initial_pose) post_pre_packing_score = sf(initial_pose) #Threshold for selection threshold = post_pre_packing_score * threshold_fraction print 'threshold:', threshold data.append('WT,' + str(post_pre_packing_score) + ',0.0,0.0,0\n') #number of residues to select from n_res = initial_pose.total_residue() #start evolution i = 0 gen = 0 while i < max_accept_mut: #update the number of generations that have pased gen += 1 #print 'accepts:', i #pick a place to mutate mut_location = random.randint(1, n_res) #get the amino acid at that position res = initial_pose.residue(mut_location) #choose the amino acid to mutate to #new_mut_key = random.randint(0,len(AAs)-1) #proposed_res = AAs[new_mut_key] proposed_res = random.choice(AAs_choice_dict[res.name1()]) #make the mutation mutant_pose = mutate_residue(initial_pose, mut_location, proposed_res, PACK_RADIUS, sf) #score mutant variant_score = sf(mutant_pose) #get the probability that the mutation will be accepted probability = calc_prob_mh(variant_score, post_pre_packing_score, N, beta, threshold) #test to see if mutation is accepted if random.random() < probability: #create a name for the mutant if its going to be kept variant_name = res.name1() + str(initial_pose.pdb_info().number( mut_location)) + str(proposed_res) #save name and energy change data.append(variant_name + "," + str(variant_score) + "," + str(variant_score - post_pre_packing_score) + "," + str(probability) + "," + str(gen) + "\n") # if i == (max_accept_mut - 1): # final_pdb_name=pdb_file.replace('.pdb', '_thresh={}_Neff={}_beta={}_i={}_nmut={}.pdb'.format(threshold_fraction, N, beta, inputs.replicate_number, i)) # mutant_pose.dump_pdb(final_pdb_name) #update the wildtype initial_pose = mutant_pose post_pre_packing_score = variant_score #update number of accepts i += 1 print '\nMutations and scoring complete.' t1 = time() # Output results. output_filename = '../Results/{}/{}_thresh={}_Neff={}_beta={}_i={}.csv'.format( prot_name, prot_name, threshold_fraction, N, beta, inputs.replicate_number) with open(output_filename, "w") as outfile: outfile.writelines(data) print 'Data written to:', output_filename print 'program takes %f' % (t1 - t0)
def main(): #read in the file made by the forward sim args = sys.argv inputfile = args[1] data = open(inputfile) first_line = data.readlines()[1] var_line=first_line.split(',') start_stab=var_line[1] #the first entry in the file is the wild type structure, calc the threshold using this threshold=float(start_stab)+10 print(threshold) # Initialize Rosetta. init(extra_options='-mute basic -mute core') # Constants PACK_RADIUS = 0 #Population size N = 100 #Beta (temp term) beta = .6 #Set up ScoreFunction sf = get_fa_scorefxn() #Set up MoveMap. mm = MoveMap() mm.set_bb(True) mm.set_chi(True) min_mover = MinMover() min_mover.movemap(mm) min_mover.score_function(sf) min_mover.min_type('dfpmin_armijo_nonmonotone') #Prepare data headers data = ['pdbfile_target,pdbfile_used,step,RevertTo,Change,Pos,From,OrgScore,RevScore,Change,Prob\n'] # Get the reversions file, the output file the score_mutant_pdb has made variant_scores=open(inputfile) #get just the mutation we want to revert to lines= variant_scores.readlines() var_line=lines[500] #gets the Nth line how ever long you want the burn to be print "staring here", var_line var_line=var_line.split(',')[0] var_loc=int(filter(str.isdigit, var_line)) var_rev=var_line[:1] gen=1 #get all the pdb files sort_list=sorted(glob.glob('*[0-9].pdb'), key=numericalSort) sort_list=sort_list[-1016:] #include the last 1000 and some pdbs, the 16 is because we want the ones that happened before the 500th mutation too. for i in range(1,len(sort_list)-30): step=-15 #calc reversion for next 15 moves for infile in sort_list[i:i+31]: #for each mutation var_line=lines[gen+500] #gets the Nth line how ever long you want the burn to be var_line=var_line.split(',')[0] print(var_line) var_loc=int(filter(str.isdigit, var_line)) var_rev="" old="" if(step<0): var_rev=var_line[len(var_line)-1:len(var_line)] old=var_line[:1] else: var_rev=var_line[:1] old=var_line[len(var_line)-1:len(var_line)] print "Current File Being Processed is: " + infile print "revering to:", var_rev print "at:", var_loc #get the pdb you want to revert and make the reversion initial_pose = pose_from_pdb(infile) mutant_pose = mutate_residue(initial_pose, var_loc , var_rev, PACK_RADIUS, sf) #repack mut task1 = standard_packer_task(mutant_pose) task1.restrict_to_repacking() task1.or_include_current(True) packer_rotamers_mover1 = RotamerTrialsMover(sf,task1) packer_rotamers_mover1.apply(mutant_pose) #repack init task2 = standard_packer_task(initial_pose) task2.restrict_to_repacking() task2.or_include_current(True) pack_rotamers_mover2 = RotamerTrialsMover(sf, task2) pack_rotamers_mover2.apply(initial_pose) #apply min mover min_mover.apply(mutant_pose) min_mover.apply(initial_pose) #get scores variant_score = sf(mutant_pose) initial_score = sf(initial_pose) #get prob probability = calc_prob_mh(variant_score, initial_score, N, beta, threshold) print(str(gen+499)+".pdb"+","+str(infile)+","+str(step)+","+ str(var_line) + ","+str(var_rev)+","+str(var_loc)+","+str(old)+"," +str(initial_score) + "," + str(variant _score) + "," + str(variant_score - initial_score)+ ","+ str(probability)+ "\n") data.append(str(gen+499)+".pdb"+","+str(infile)+","+str(step)+","+ str(var_line) + ","+str(var_rev)+","+str(var_loc)+","+str(old)+"," +str(initial_score) + "," + str(v ariant_score) + "," + str(variant_score - initial_score)+ ","+ str(probability)+ "\n") step=step+1 gen+=1 print '\nDONE' data_filename = 'premutate_rep1_bb_T_ch_T.csv' with open(data_filename, "w") as f: f.writelines(data)
def mutate_residue(pose, mutant_position, mutant_aa, pack_radius=0.0, pack_scorefxn=''): """Replace the residue at <mutant_position> in <pose> with <mutant_aa> and repack any residues within <pack_radius> angstroms of the mutating residue's center (nbr_atom) using <pack_scorefxn> Note: <mutant_aa> is the single letter name for the desired ResidueType Example: mutate_residue(pose, 30, "A") See also: Pose PackRotamersMover """ if not pose.is_fullatom(): IOError('mutate_residue() only works with full-atom poses.') test_pose = rosetta.Pose() test_pose.assign(pose) # create a standard scorefxn by default if not pack_scorefxn: pack_scorefxn = rosetta.get_fa_scorefxn() task = rosetta.standard_packer_task(test_pose) task.or_include_current(True) # A vector1 of booleans (a specific object) is needed for specifying the # mutation. This demonstrates another more direct method of setting # PackerTask options for design. aa_bool = rosetta.utility.vector1_bool() # PyRosetta uses several ways of tracking amino acids (ResidueTypes). # The numbers 1-20 correspond individually to the 20 proteogenic amino # acids. aa_from_oneletter_code() returns the integer representation of an # amino acid from its one letter code # Convert mutant_aa to its integer representation. mutant_aa = rosetta.aa_from_oneletter_code(mutant_aa) # The mutation is performed by using a PackerTask with only the mutant # amino acid available during design. To do this, we construct a vector1 # of booleans indicating which amino acid (by its numerical designation; # see above) to allow. for i in range(1, 20 + 1): # In Python, logical expression are evaluated with priority, thus the # line below appends to aa_bool the truth (True or False) of the # statement i == mutant_aa. aa_bool.append(i == mutant_aa) # Modify the mutating residue's assignment in the PackerTask using the # vector1 of booleans across the proteogenic amino acids. task.nonconst_residue_task(mutant_position).restrict_absent_canonical_aas( aa_bool) # Prevent residues from packing by setting the per-residue "options" of # the PackerTask. center = pose.residue(mutant_position).nbr_atom_xyz() for i in range(1, pose.total_residue() + 1): # Only pack the mutating residue and any within the pack_radius if not i == mutant_position or center.distance_squared( test_pose.residue(i).nbr_atom_xyz()) > pack_radius**2: task.nonconst_residue_task(i).prevent_repacking() # Apply the mutation and pack nearby residues. packer = rosetta.PackRotamersMover(pack_scorefxn, task) packer.apply(test_pose) return test_pose
def main(): #takes name of pdb file without the extention args = sys.argv pdb_file = args[1] #set up timer to figure out how long the code took to run t0 = time() # Initialize Rosetta. init(extra_options='-mute basic -mute core') # Constants PACK_RADIUS = 10.0 #Amino acids, notice there is no C AAs = ("A", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "V", "W", "Y") #Number of mutations to accept max_accept_mut = 1500 #Population size N = 100 #Beta (temp term) beta = 1 #Prepare data headers data = ['Variant,Rosetta Score,"delta-delta-G",Probability,Generation\n'] #Load and clean up pdb file name = pdb_file + ".pdb" cleanATOM(name) clean_name = pdb_file + ".clean.pdb" initial_pose = pose_from_pdb(clean_name) #Set up ScoreFunction sf = get_fa_scorefxn() #Set up MoveMap. mm = MoveMap() #change these for more or less flexability mm.set_bb(True) mm.set_chi(True) #Pack and minimize initial pose to remove clashes. pre_pre_packing_score = sf(initial_pose) task = standard_packer_task(initial_pose) task.restrict_to_repacking() task.or_include_current(True) pack_rotamers_mover = RotamerTrialsMover(sf, task) pack_rotamers_mover.apply(initial_pose) min_mover = MinMover() min_mover.movemap(mm) min_mover.score_function(sf) min_mover.min_type('dfpmin_armijo_nonmonotone') min_mover.apply(initial_pose) post_pre_packing_score = sf(initial_pose) #Set threshold for selection threshold = pre_pre_packing_score / 2 data.append('WT,' + str(post_pre_packing_score) + ',0.0 ,0.0,0\n') #number of residues to select from n_res = initial_pose.total_residue() #start sim i = 0 gen = 0 while i < max_accept_mut: #update the number of generations that have pased gen += 1 print 'accepts:', i #pick a place to mutate mut_location = random.randint(1, n_res) #get the amino acid at that position res = initial_pose.residue(mut_location) #don't mess with C, just choose again while (res.name1() == 'C'): mut_location = random.randint(1, n_res) #get the amino acid at that position res = initial_pose.residue(mut_location) #choose the amino acid to mutate to new_mut_key = random.randint(0, len(AAs) - 1) proposed_res = AAs[new_mut_key] #don't bother mutating to the same amino acid it just takes more time while (proposed_res == res.name1()): new_mut_key = random.randint(0, len(AAs) - 1) proposed_res = AAs[new_mut_key] #make the mutation #this is actually a really bad model, and probably shouldnt be used. In new version is repack the whole thing, then reminimize, I should also backrub it. mutant_pose = mutate_residue(initial_pose, mut_location, proposed_res, PACK_RADIUS, sf) #score mutant variant_score = sf(mutant_pose) #get the probability that the mutation will be accepted probability = calc_prob_mh(variant_score, post_pre_packing_score, N, beta, threshold) #test to see if mutation is accepted if random.random() < probability: #create a name for the mutant if its going to be kept variant_name = res.name1() + str(initial_pose.pdb_info().number( mut_location)) + str(proposed_res) # Assuming 1000 burn in phase, take this if out if you want to store everything if i > 1000: #save name and energy change data.append(variant_name + "," + str(variant_score) + "," + str(variant_score - post_pre_packing_score) + "," + str(probability) + "," + str(gen) + "\n") pdb_name = str(i) + ".pdb" mutant_pose.dump_pdb(pdb_name) #update the wildtype initial_pose = mutant_pose post_pre_packing_score = variant_score #update number of accepts i += 1 print '\nMutations and scoring complete.' t1 = time() # Output results. data_filename = pdb_file[:-5] + 'mh_1500_rep3.csv' with open(data_filename, "w") as f: f.writelines(data) print 'Data written to:', data_filename print 'program takes %f' % (t1 - t0)
if not args.mm: sf.set_weight(fa_elec, sf.get_weight(fa_elec) * args.elec_mult) sf.set_weight(fa_sol, sf.get_weight(fa_sol) * args.sol_mult) target_atr = sf.get_weight(fa_atr) * args.atr_mult target_rep = sf.get_weight(fa_rep) * args.rep_mult sf.set_weight(fa_atr, target_atr) sf.set_weight(fa_rep, target_rep) print ' Starting Score:' sf.show(starting_pose) print ' Interface score: ', print round( calc_interaction_energy(starting_pose, sf, Vector1([JUMP_NUM])), 2) if args.prepack: # Prepare PackerTask pt = standard_packer_task(starting_pose) pt.restrict_to_repacking() pt.or_include_current(True) # Prepare the packer. pre_packer = PackRotamersMover(sf, pt) # Pre-pack the pose. print '\nPre-packing the pose (slow)...' pre_packer.apply(starting_pose) print ' Success!' print ' Pre-packed score:' sf.show(starting_pose) print ' Interface score: ', print round( calc_interaction_energy(starting_pose, sf, Vector1([JUMP_NUM])), 2)
# Load pdb file. initial_pose = pose_from_pdb(args.pdb_filename) # Set up ScoreFunction. sf = get_fa_scorefxn() # Set up MoveMap. mm = MoveMap() mm.set_bb(True) mm.set_chi(True) # Pack and minimize initial pose to remove clashes. pre_pre_packing_score = sf(initial_pose) task = standard_packer_task(initial_pose) task.restrict_to_repacking() task.or_include_current(True) pack_rotamers_mover = RotamerTrialsMover(sf, task) pack_rotamers_mover.apply(initial_pose) min_mover = MinMover() min_mover.movemap(mm) min_mover.score_function(sf) min_mover.min_type('linmin') if args.minimize: min_mover.apply(initial_pose) post_pre_packing_score = sf(initial_pose) print
sf.set_weight(fa_intra_rep, sf.get_weight(fa_rep) * args.rep_mult) sf.set_weight(fa_sol, sf.get_weight(fa_sol) * args.sol_mult) if not args.mm: sf.set_weight(fa_elec, sf.get_weight(fa_elec) * args.elec_mult) # Set filenames. output_base_filename = args.pdb_filename[:-4] + '_refined' if args.pm: pose.pdb_info().name(output_base_filename) pm = PyMOL_Mover() visualize(pose) # Set up packer. pt = standard_packer_task(pose) pt.restrict_to_repacking() pt.or_include_current(True) packer = RotamerTrialsMover(sf, pt) # Prepack. packer.apply(pose) visualize(pose) print ' Score after prepacking:', sf(pose) sf.show(pose) # TEMP # Fold the polysaccharide. print 'Folding/Refining structural polysaccharide with', print pose.total_residue(), #print pose.residue(2).carbohydrate_info().short_name(), 'residues...'
def main(): #takes name of pdb file without the extention args = sys.argv pdb_file = args[1] #set up timer to figure out how long the code took to run t0 = time() # Initialize Rosetta. init(extra_options='-mute basic -mute core') # Constants PACK_RADIUS = 10.0 #Amino acids, notice there is no C AAs = ("A", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "V", "W", "Y") #Number of mutations to accept max_accept_mut = 5000 #Population size N = 100 #Beta (temp term) beta = 1 #Prepare data headers data = ['Variant,Rosetta Score,"delta-delta-G",Probability,Generation\n'] #Load and clean up pdb file name = pdb_file + ".pdb" cleanATOM(name) clean_name = pdb_file + ".clean.pdb" initial_pose = pose_from_pdb(clean_name) #Set up ScoreFunction sf = get_fa_scorefxn() #Set up MoveMap. mm = MoveMap() mm.set_bb(True) mm.set_chi(True) #Pack and minimize initial pose to remove clashes. pre_pre_packing_score = sf(initial_pose) task = standard_packer_task(initial_pose) task.restrict_to_repacking() task.or_include_current(True) pack_rotamers_mover = RotamerTrialsMover(sf, task) pack_rotamers_mover.apply(initial_pose) min_mover = MinMover() min_mover.movemap(mm) min_mover.score_function(sf) min_mover.min_type('dfpmin_armijo_nonmonotone') min_mover.apply(initial_pose) post_pre_packing_score = sf(initial_pose) pdb_name = str(pdb_file) + "_min.pdb" initial_pose.dump_pdb(pdb_name) #Set threshold for selection #threshold = post_pre_packing_score/2 #threshold = post_pre_packing_score data.append(str(pdb_file) + str(post_pre_packing_score) + ',0.0,0.0,0\n') data_filename = pdb_file + '.score' with open(data_filename, "w") as f: f.writelines(data) print 'Data written to:', data_filename '''