Project: s41467-025-56036-0 | Function: SIMULATE_TRAJ (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Implements the core geometry-based kinetic simulation of DNA-AuNP motor using the Gillespie Algorithm to model stochastic reaction processes including DNA/RNA hybridization, RNase H binding, and RNA hydrolysis that drive motor motion

**KEY TERMS:** {
  "khyb": "DNA/RNA hybridization rate constant (k_on^DNA/RNA)",
  "konE": "RNase H binding rate constant (k_on^E)",
  "kcat": "RNA hydrolysis rate constant (k_cat^E)",
  "RNA_state": "state matrix tracking RNA molecules (unbound/hybridized/hydrolyzed)",
  "DNA_state": "state matrix tracking DNA-RNA interactions",
  "Gillespie algorithm": "stochastic simulation algorithm for chemical reactions"
}

**CONTEXT CODE:** print ("path_RNA_molecules",path_RNA_molecules)
print ('R_mobile_pixel', R_mobile_pixel)
print ('R_mobile nm', R_mobile_nm)

print('path_radius (nm)',path_radius)
print ('r_path nm', r_path *pixel_to_nm)
print ('r_path px', r_path )
print ("DNA_size",DNA_size)

###############################################################################
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
############################# variable parameters ############################# 
############################# variable parameters ############################# 
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
###############################################################################
# Basic parameters
globalfol = r'Directory\to\perform\DNAmotor\simulation'
date = 'DATE'
RNA_size = 2000                        # Full range of RNA substrate (px)  (default:2000)
tmax_simu = 100000                     # Uplimit for simulation (sec)  (default:100000)
N_simu = 3                             # Nunber of trajectory generate (default:5)
frame_per_event = 1000                 # Span frame to check the progress of simulation (default:1000)
foli=0                                 # ID of the condition of kinetic parameters (default:0)
# Kinetic parameters
khyb_list = np.array([0.2])                  # DNA/RNA Hybridization rate [s-1]
konE_list = np.array([1.0]) *10**6           # RNase H binding rate [M-1 s-1]
kcat_list = np.array([3])                    # RNA hydrolysis rate [s-1] 
RNaseH_list = np.array([36])                 # RNase H condition [nM]
#######################
SIMULATION = True # Run the new simulation
SUMMERIZE = True # Output rough summary of the simulation
#!!!!!!!!!!!!!!!!
#########################################################################################################################################################################################
#########################################################################################################################################################################################
colortable_RNA = ListedColormap(['0.7','g','r','w']) # ['Unbound', 'Bound', 'Hydrolyzed', 'Empty']


def CENTER_TRANSLOCATE(cx, cy, DNA_state, cx_list, cy_list, i):
    # MASKED: Implements the core geometric constraint algorithm that determines DNA-AuNP motor position
    # by calculating overlapping mobile regions of DNA/RNA duplexes and randomly selecting new positions
    # within the constrained area, modeling tethered-particle motion
    raise NotImplementedError("This function is masked for testing purposes.")





t01_sum,t12_sum,t23_sum,t34_sum,t45_sum,t56_sum,t67_sum = 0,0,0,0,0,0,0
t2_01_sum,t2_12_sum,t2_23_sum = 0,0,0

def SIMULATE_TRAJ(i_traj, trace_fol, khyb, konE, kcat):
    # MASKED: Implements the core geometry-based kinetic simulation of DNA-AuNP motor
    # using the Gillespie Algorithm to model stochastic reaction processes including
    # DNA/RNA hybridization, RNase H binding, and RNA hydrolysis that drive motor motion
    raise NotImplementedError("This function is masked for testing purposes.")





#################################################################################
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Main program
global khyb, konE, kcat
for khyb in khyb_list:
    for konE in konE_list:
        for kcat in kcat_list:
            foli+=1
            foli_str =  ('000' + str(foli))[-3:]
            khyb_str = f"khyb={khyb:.2f}"
            kcat_str = f"kcatE={kcat:.1f}"
            konE_scaled = konE / 10**6
            konE_str = f"konE={konE_scaled:.1f}x106"
            # Combine string
            dirname = foli_str + '_' + f"{khyb_str}_{kcat_str}_{konE_str}"
            print('############################################')
            print('############################################')
            print(dirname)
            print('############################################')
            print('############################################')
            # make working folder
            workfol = globalfol + os.sep +  dirname
            folder_maker(workfol)            

            #start simulation for preset RNase H
            for RNaseH in RNaseH_list:
                print('RNaseH ' + str(RNaseH) + ' nM')
            
                keys = {'RNA_size':RNA_size,'N_simu':N_simu,'tmax':tmax_simu,'khyb':khyb,'kcat':kcat,'konE':konE,'RNaseH':RNaseH\
                        ,'particle_size':particle_size,'RNA_density':RNA_density,'DNA_density':DNA_density,'L_DNA':L_DNA\
                        ,'R_mobile_nm':R_mobile_nm,'frame_per_event':frame_per_event}                
                title_params = ['RNaseH','N_simu','tmax','frame_per_event']
                title_keys = {k: v for k, v in keys.items() if k in title_params}
                                
                savefol = workfol + os.sep + date + '_'+ str(title_keys).replace(':','=')
                folder_maker(savefol)                
                trajfol = savefol + os.sep + 'progress'
                folder_maker(trajfol)
                # save the parameter used.
                ####################################################################################
                df_params = pd.DataFrame(keys, index=[0])
                df_params.to_csv(savefol + os.sep + 'parameters.csv')
                ###############################################################################
                
                if SIMULATION:
                    # Run simulations for "N_simu" times
                    for i_traj in range(N_simu):
                        start = time.time()
                        trace_i_str = ('0000'+str(i_traj))[-3:]
                        trace_fol = trajfol + os.sep + trace_i_str
                        folder_maker(trace_fol)
                        print("\n################################################################################")
                        print("################################################################################")
                        print('simulation file is \n')
                        print(trajfol + os.sep + ('0000'+str(i_traj))[-4:] +'.png')
                        print('\n')    

                
                        if os.path.isfile(trajfol + os.sep + ('0000'+str(i_traj))[-4:] +'.png'):
                            print('file exist. Skip this')
                            continue        
                        #################################################################################
                        #################################################################################
                        df_traj = SIMULATE_TRAJ(i_traj,trace_fol, khyb,konE* RNaseH *10**-9, kcat )
                        df_traj.to_csv(trajfol + os.sep + ('00000'+str(i_traj))[-4:]+".csv")
                        #################################################################################
                        #################################################################################
                
                        trace_i_str = ('0000'+str(i_traj))[-3:]
                        if frame_per_event==1:
                          #  command = r'ffmpeg -y -framerate 100 -i "'+trace_i_str+os.sep+trace_i_str+ '_%06d.png" -c:v libx264 -preset slow -crf 22 '+trace_i_str+ '.avi'
                            command = r'ffmpeg -y -framerate 100 -i "'+trace_i_str+os.sep+trace_i_str+ '_%06d.png" -vf crop=iw:680:0:0 -pix_fmt yuv420p -c:v libx264 -preset slow  -crf 18 '+trace_i_str+ '.mp4'            
                            print(command)
                            p = subprocess.run(command, stdout=subprocess.PIPE, shell=True, cwd=trajfol,universal_newlines=True)




                if SUMMERIZE:
                    df_traj_sum = pd.DataFrame()
                    for i_traj in tqdm(range(N_simu)):
                        print(trajfol + os.sep + ('00000'+str(i_traj))[-4:]+".csv")
                        df = pd.read_csv(trajfol + os.sep + ('00000'+str(i_traj))[-4:]+".csv", index_col = None)
                        df_traj_sum = pd.concat([df_traj_sum,df])
                    df_traj_sum.to_pickle(savefol + os.sep + 'df_traj.gs')
                   
                    
                    # plot trajectories


Complete the function implementation replacing "raise NotImplementedError".