docstr: Make a GenePattern file containing image measurements
  Format specifications located at http://www.broadinstitute.org/cancer/software/genepattern/tutorial/gp_fileformats.html?gct
  
  file_name - create a file with this name
  image_set_numbers - the image sets whose data gets extracted
  workspace - workspace containing the measurements
docstr_tok: ["Make","a","GenePattern","file","containing","image","measurements","Format","specifications","located","at","http",":","\/\/www.broadinstitute.org\/cancer\/software\/genepattern\/tutorial\/gp_fileformats.html","?","gct","file_name","-","create","a","file","with","this","name","image_set_numbers","-","the","image","sets","whose","data","gets","extracted","workspace","-","workspace","containing","the","measurements"]
code: def make_gct_file(self, image_set_numbers, workspace, settings_group):
      """Make a GenePattern file containing image measurements
      Format specifications located at http://www.broadinstitute.org/cancer/software/genepattern/tutorial/gp_fileformats.html?gct
  
      file_name - create a file with this name
      image_set_numbers - the image sets whose data gets extracted
      workspace - workspace containing the measurements
      """
  
      file_name = self.make_gct_file_name(
          workspace, image_set_numbers[0], settings_group
      )
  
      def ignore_feature(feature_name):
          """Return true if we should ignore a feature"""
          if (
              is_file_name_feature(feature_name)
              or is_path_name_feature(feature_name)
              or feature_name.startswith("ImageNumber")
              or feature_name.startswith("Group_Number")
              or feature_name.startswith("Group_Index")
              or feature_name.startswith("Description_")
              or feature_name.startswith("ModuleError_")
              or feature_name.startswith("TimeElapsed_")
              or feature_name.startswith("ExecutionTime_")
              or feature_name.startswith(C_URL)
              or feature_name.startswith(C_MD5_DIGEST)
              or feature_name.startswith(C_SCALING)
              or feature_name.startswith(C_HEIGHT)
              or feature_name.startswith(C_WIDTH)
          ):
              return True
          return False
  
      m = workspace.measurements
      image_features = m.get_feature_names(IMAGE)
      image_features.insert(0, IMAGE_NUMBER)
  
      fd = open(file_name, "w", newline="")
      try:
          writer = csv.writer(fd, delimiter="\t")
          for img_number in image_set_numbers:
              aggs = []
              if self.wants_aggregate_means:
                  aggs.append(AGG_MEAN)
              if self.wants_aggregate_medians:
                  aggs.append(AGG_MEDIAN)
              if self.wants_aggregate_std:
                  aggs.append(AGG_STD_DEV)
              agg_measurements = m.compute_aggregate_measurements(
                  img_number, aggs
              )
  
              if img_number == image_set_numbers[0]:
                  ordered_agg_names = list(agg_measurements.keys())
                  ordered_agg_names.sort()
                  image_features += ordered_agg_names
                  image_features.sort()
                  image_features = self.filter_columns(
                      image_features, IMAGE
                  )
                  if image_features is None:
                      return
  
                  # Count # of actual measurements
                  num_measures = 0
                  for feature_name in image_features:
                      if (
                          not ignore_feature(feature_name)
                          or feature_name in agg_measurements
                      ):
                          num_measures += 1
  
                  writer.writerow(["#1.2"])
                  writer.writerow(
                      [len(image_set_numbers), num_measures]
                  )
  
                  # Keep measurements only
                  measurement_feature_names = [
                      x for x in image_features if not ignore_feature(x)
                  ]
  
                  # The first headers need to be 'NAME' and 'Description'
                  written_image_names = [
                      "NAME",
                      "Description",
                  ] + measurement_feature_names
                  writer.writerow(written_image_names)
  
                  (
                      name_feature,
                      description_feature,
                  ) = self.validate_image_features_exist(image_features)
  
                  if name_feature == []:
                      return
  
                  image_features = [
                      name_feature[0],
                      description_feature[0],
                  ] + measurement_feature_names
  
              # Output all measurements
              row = [
                  agg_measurements[feature_name]
                  if feature_name in agg_measurements
                  else m.get_measurement(
                      IMAGE, feature_name, img_number
                  )
                  for feature_name in image_features
              ]
              row = [
                  "" if x is None else x if numpy.isscalar(x) else x[0]
                  for x in row
              ]
              writer.writerow(row)
      finally:
          fd.close()
  
imports: import base64
  import csv
  import logging
  import os
  import numpy
  from cellprofiler_core.constants.image import C_MD5_DIGEST, C_SCALING, C_HEIGHT, C_WIDTH
  from cellprofiler_core.constants.measurement import EXPERIMENT, IMAGE, AGG_MEAN, AGG_MEDIAN, AGG_STD_DEV, C_URL, C_PATH_NAME, C_FILE_NAME, NEIGHBORS, R_FIRST_IMAGE_NUMBER, R_SECOND_IMAGE_NUMBER, R_FIRST_OBJECT_NUMBER, R_SECOND_OBJECT_NUMBER
  from cellprofiler_core.constants.module import IO_FOLDER_CHOICE_HELP_TEXT, IO_WITH_METADATA_HELP_TEXT, USING_METADATA_HELP_REF, USING_METADATA_TAGS_REF
  from cellprofiler_core.constants.pipeline import EXIT_STATUS
  from cellprofiler_core.measurement import Measurements
  from cellprofiler_core.module import Module
  from cellprofiler_core.preferences import ABSOLUTE_FOLDER_NAME
  from cellprofiler_core.preferences import DEFAULT_INPUT_FOLDER_NAME
  from cellprofiler_core.preferences import DEFAULT_INPUT_SUBFOLDER_NAME
  from cellprofiler_core.preferences import DEFAULT_OUTPUT_FOLDER_NAME
  from cellprofiler_core.preferences import DEFAULT_OUTPUT_SUBFOLDER_NAME
  from cellprofiler_core.preferences import get_headless
  from cellprofiler_core.setting import Binary
  from cellprofiler_core.setting import Divider
  from cellprofiler_core.setting import Measurement
  from cellprofiler_core.setting import SettingsGroup
  from cellprofiler_core.setting import ValidationError
  from cellprofiler_core.setting.choice import CustomChoice, Choice
  from cellprofiler_core.setting.do_something import DoSomething, RemoveSettingButton
  from cellprofiler_core.setting.multichoice import MeasurementMultiChoice
  from cellprofiler_core.setting.subscriber import ImageSubscriber, LabelSubscriber
  from cellprofiler_core.setting.text import Directory, Text
  from cellprofiler_core.utilities.core.modules.load_data import is_file_name_feature, is_path_name_feature
  from cellprofiler_core.utilities.measurement import find_metadata_tokens, get_agg_measurement_name
  from cellprofiler.gui.help.content import MEASUREMENT_NAMING_HELP
label_desc: Use image node_id 26 for calling the ExportToSpreadsheet obj's underlying member method code with example usage: obj.make_gct_file(image_set_numbers, workspace, settings_group) and returns: False, True