Project: s41467-024-46089-y | Function: get_model (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:** Creates Siamese neural network architecture for compound-target prediction using FRoGS embeddings

**KEY TERMS:** {
  "input_l": "compound signature embedding",
  "input_r": "target gene embedding",
  "denselayers": "shared dense transformation",
  "merge": "element-wise multiplication",
  "denseclassifier": "binary classification head",
  "logit": "prediction logits"
}

**CONTEXT CODE:** import sys
import pandas as pd
import numpy as np
import os
import glob
import math
import csv
import tensorflow as tf
from utils import parallel
from tensorflow.python.keras import backend as K
from tensorflow.keras import layers, losses
from tensorflow import keras
from tensorflow.keras.models import Model
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.preprocessing import normalize
import argparse

def parse_args():
    parser = argparse.ArgumentParser(description='Train l1000 model')
    parser.add_argument('--cpdlist_file', default='../data/compound_list_test.txt',
                        help='Path to a file that lists the compounds for test')
    parser.add_argument('--sig_file', default='../data/L1000_PhaseI_and_II.csv',
                        help='Path to a file containing L1000 gene signatures')
    parser.add_argument('--perttype', default='shRNA',
                        help='Perturbagen type of gene signatures to use. cDNA or shRNA')
    parser.add_argument('--emb_go', default='../data/gene_vec_go_256.csv',
                        help='Gene embeddings learned from GO annotations')
    parser.add_argument('--emb_archs4', default='../data/gene_vec_archs4_256.csv',
                        help='Gene embeddings learned from archs4 gene expression experiments')
    parser.add_argument('--outdir', default='../results/',
                        help='Path to a directory to save prediction lists')
    return parser.parse_args()


def get_model(fp_dim, hid_dim = 2048):
    # MASKED: Creates Siamese neural network architecture for compound-target prediction using FRoGS embeddings implementation
    raise NotImplementedError("This function is masked for testing purposes.")

def gene_sim_mean_std():
    '''Compute the mean and standard diviation of each gene's cosine
       similarities with all the genes in the dataset
       return: a mapping from each gene ID to the mean of its
               similarities with all the genes in the dataset;
               a mapping from each gene ID to the standard diviation of its
               similarities with all the genes in the dataset
    '''
    all_genes=set(list(go_emb.keys()) + list(archs4_emb.keys()))

    def sim_mean_std(emb):
        emb_mat=[]
        gene_ids=[]
        for i,gid in enumerate(all_genes):
            if gid in emb:
                emb_mat.append(emb[gid])
                gene_ids.append(gid)

        emb_mat=np.vstack(emb_mat)
        sim_pairwise=cosine_similarity(emb_mat, emb_mat)
        sim_mean=np.mean(sim_pairwise, axis=1)
        sim_std=np.std(sim_pairwise, axis=1)

        mean_std_dict={}
        for i,gid in enumerate(gene_ids):
            mean_std_dict[gid]=(sim_mean[i], sim_std[i])

        return mean_std_dict

    return sim_mean_std(go_emb), sim_mean_std(archs4_emb)

def get_vec(X):
    sig2vec = {}
    l1k, S_hit = X
    vec = compute_list_emb(S_hit)
    sig2vec[l1k] = vec
    return sig2vec

def infer_new(classifier_0, classifier_1, classifier_2, cpd_test):
    tgtcl_idx = {}
    for cl in all_cl:
        tgt_sig = pert_sig[pert_sig['Perturbagen']==perttype].copy()
        tgt_sig = tgt_sig[tgt_sig['CellLine']==cl]
        tgtcl_idx[cl] = tgt_sig.index
    for k,cpd in enumerate(cpd_test):
        print(k, len(cpd_test), cpd)
        cpd_sig = pert_sig[pert_sig['Name']==cpd]
        cpd_sig_cl_df = {cl:cpd_sig_cl for cl, cpd_sig_cl in cpd_sig.groupby('CellLine')}
        for cl in cpd_sig_cl_df:
            cpd_sig_cl = cpd_sig_cl_df[cl]
            if len(cpd_sig_cl) == 0 or len(tgtcl_idx[cl]) == 0:
                continue

            tgt_idx = {}
            scnt = 0
            test_input_idx_l = []
            test_input_idx_r = []
            for tidx in tgtcl_idx[cl]:
                tgt_idx[pert_sig.loc[tidx, 'Name']] = []
            for cidx in cpd_sig_cl.index:
                for tidx in tgtcl_idx[cl]:
                    test_input_idx_l.append(cidx)
                    test_input_idx_r.append(tidx)
                    tgt_idx[pert_sig.loc[tidx, 'Name']].append(scnt)
                    scnt += 1

            test_input_l = sigvec_all[test_input_idx_l]
            test_input_r = sigvec_all[test_input_idx_r]
            scores_0 = classifier_0.predict([test_input_l, test_input_r])
            scores_0 = 1 / (1 + np.exp(-scores_0))
            scores_1 = classifier_1.predict([test_input_l, test_input_r])
            scores_1 = 1 / (1 + np.exp(-scores_1))
            scores_2 = classifier_2.predict([test_input_l, test_input_r])
            scores_2 = 1 / (1 + np.exp(-scores_2))
            scores = (scores_0 + scores_1 + scores_2) / 3
            genes = []
            max_scores = []
            for k in tgt_idx:
                genes.append(k)
                max_scores.append(np.max(scores[tgt_idx[k]]))
            max_scores = np.array(max_scores)
            genes = np.array(genes)
            sortidx = np.argsort(-max_scores)
            topgenes = genes[sortidx]
            rankedscores = max_scores[sortidx]
            fw = open(outdir + cpd + cl + '_' + perttype + '.txt', 'w')
            fw.write('gene\trank\tscore\n')
            for i in range(len(topgenes)):
                fw.write(topgenes[i].split('@')[0] + '\t' + str(i+1) + '\t' + str(rankedscores[i]) + '\n')
            fw.close()

def compute_list_emb(glist):
    '''Compute the vector representation (embedding) for an input gene list
       input: list of gene IDs
       return: a 512d vector reprsentation
    '''


Complete the function implementation replacing "raise NotImplementedError".