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.
      """
  
      motif1_generator = ReverseComplementWrapper(
          PwmSamplerFromLoadedMotifs(loaded_motifs, motif1)
      )
      motif2_generator = ReverseComplementWrapper(
          PwmSamplerFromLoadedMotifs(loaded_motifs, motif2)
      )
      separation_generator = UniformIntegerGenerator(
          min_spacing, max_spacing
      )
      embedder = EmbeddableEmbedder(
          PairEmbeddableGenerator(
              motif1_generator, motif2_generator, separation_generator
          )
      )
      embed_in_background = EmbedInABackground(
          ZeroOrderBackgroundGenerator(
              seq_length,
              discreteDistribution=get_distribution(GC_fraction),
          ),
          [embedder],
      )
      generated_sequences = tuple(
          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/contrib/dragonn/simulations.py
imports: from __future__ import absolute_import, division, print_function
  from collections import OrderedDict
  import numpy
  import simdna
  from simdna.synthetic import RepeatedEmbedder, SubstringEmbedder, ReverseComplementWrapper, UniformPositionGenerator, InsideCentralBp, LoadedEncodeMotifs, PwmSamplerFromLoadedMotifs, UniformIntegerGenerator, ZeroOrderBackgroundGenerator, EmbedInABackground, GenerateSequenceNTimes, RandomSubsetOfEmbedders, IsInTraceLabelGenerator, EmbeddableEmbedder, PairEmbeddableGenerator
  from simdna.util import DiscreteDistribution
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