code: def simulate_heterodimer_grammar(
      motif1,
      motif2,
      seq_length,
      min_spacing,
      max_spacing,
      num_pos,
      num_neg,
      GC_fraction,
  ):
      """Simulates two classes of sequences with motif1 and motif2:
          - Positive class sequences with motif1 and motif2 positioned min_spacing and max_spacing
          - Negative class sequences with independent motif1 and motif2 positioned anywhere in the sequence, not as a heterodimer grammar
  
      Parameters
      ----------
      seq_length : int, length of sequence
      GC_fraction : float, GC fraction in background sequence
      num_pos : int, number of positive class sequences
      num_neg : int, number of negatice class sequences
      motif1 : str, encode motif name
      motif2 : str, encode motif name
      min_spacing : int, minimum inter motif spacing
      max_spacing : int, maximum inter motif spacing
  
      Returns
      -------
      sequence_arr : 1darray
          Array with sequence strings.
      y : 1darray
          Array with positive/negative class labels.
      embedding_arr: list
          List of embedding objects.
      """
      import simdna
      from simdna import synthetic
  
      loaded_motifs = synthetic.LoadedEncodeMotifs(
          simdna.ENCODE_MOTIFS_PATH, pseudocountProb=0.001
      )
      motif1_generator = synthetic.ReverseComplementWrapper(
          synthetic.PwmSamplerFromLoadedMotifs(loaded_motifs, motif1)
      )
      motif2_generator = synthetic.ReverseComplementWrapper(
          synthetic.PwmSamplerFromLoadedMotifs(loaded_motifs, motif2)
      )
      separation_generator = synthetic.UniformIntegerGenerator(
          min_spacing, max_spacing
      )
      embedder = synthetic.EmbeddableEmbedder(
          synthetic.PairEmbeddableGenerator(
              motif1_generator, motif2_generator, separation_generator
          )
      )
      embed_in_background = synthetic.EmbedInABackground(
          synthetic.ZeroOrderBackgroundGenerator(
              seq_length,
              discreteDistribution=get_distribution(GC_fraction),
          ),
          [embedder],
      )
      generated_sequences = tuple(
          synthetic.GenerateSequenceNTimes(
              embed_in_background, num_pos
          ).generateSequences()
      )
      grammar_sequence_arr = np.array(
          [generated_seq.seq for generated_seq in generated_sequences]
      )
      positive_embedding_arr = [
          generated_seq.embeddings
          for generated_seq in generated_sequences
      ]
      (
          nongrammar_sequence_arr,
          _,
          negative_embedding_arr,
      ) = simulate_multi_motif_embedding(
          [motif1, motif2], seq_length, 2, 2, num_neg, GC_fraction
      )
      sequence_arr = np.concatenate(
          (grammar_sequence_arr, nongrammar_sequence_arr)
      )
      y = np.array([[True]] * num_pos + [[False]] * num_neg)
      embedding_arr = positive_embedding_arr + negative_embedding_arr
      return sequence_arr, y, embedding_arr
  
file_path: deepchem/deepchem/molnet/dnasim.py
imports: import numpy
label_desc: Use image node_id 9 for calling a global function with example usage: simulate_heterodimer_grammar(motif1, motif2, seq_length, min_spacing, max_spacing, num_pos, num_neg, GC_fraction) and returns: sequence_arr,  y,  embedding_arr