nodes: 0, module; 1, function_definition; 2, function_name:create; 3, parameters; 4, block; 5, identifier:filename; 6, identifier:spec; 7, expression_statement; 8, import_from_statement; 9, if_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, if_statement; 15, if_statement; 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, expression_statement; 20, if_statement; 21, expression_statement; 22, if_statement; 23, expression_statement; 24, return_statement; 25, comment:"""Create a new segy file.
  
      Create a new segy file with the geometry and properties given by `spec`.
      This enables creating SEGY files from your data. The created file supports
      all segyio modes, but has an emphasis on writing. The spec must be
      complete, otherwise an exception will be raised. A default, empty spec can
      be created with ``segyio.spec()``.
  
      Very little data is written to the file, so just calling create is not
      sufficient to re-read the file with segyio. Rather, every trace header and
      trace must be written to the file to be considered complete.
  
      Create should be used together with python's ``with`` statement. This ensure
      the data is written. Please refer to the examples.
  
      The ``segyio.spec()`` function will default sorting, offsets and everything
      in the mandatory group, except format and samples, and requires the caller
      to fill in *all* the fields in either of the exclusive groups.
  
      If any field is missing from the first exclusive group, and the tracecount
      is set, the resulting file will be considered unstructured. If the
      tracecount is set, and all fields of the first exclusive group are
      specified, the file is considered structured and the tracecount is inferred
      from the xlines/ilines/offsets. The offsets are defaulted to ``[1]`` by
      ``segyio.spec()``.
  
      Parameters
      ----------
      filename : str
          Path to file to create
      spec : segyio.spec
          Structure of the segy file
  
      Returns
      -------
      file : segyio.SegyFile
          An open segyio file handle, similar to that returned by `segyio.open`
  
      See also
      --------
      segyio.spec : template for the `spec` argument
  
  
      Notes
      -----
  
      .. versionadded:: 1.1
  
      .. versionchanged:: 1.4
         Support for creating unstructured files
  
      .. versionchanged:: 1.8
         Support for creating lsb files
  
      The ``spec`` is any object that has the following attributes
  
      Mandatory::
  
          iline   : int or segyio.BinField
          xline   : int or segyio.BinField
          samples : array of int
          format  : { 1, 5 }
              1 = IBM float, 5 = IEEE float
  
      Exclusive::
  
          ilines  : array_like of int
          xlines  : array_like of int
          offsets : array_like of int
          sorting : int or segyio.TraceSortingFormat
  
          OR
  
          tracecount : int
  
      Optional::
  
          ext_headers : int
          endian : str { 'big', 'msb', 'little', 'lsb' }
              defaults to 'big'
  
  
      Examples
      --------
  
      Create a file:
  
      >>> spec = segyio.spec()
      >>> spec.ilines  = [1, 2, 3, 4]
      >>> spec.xlines  = [11, 12, 13]
      >>> spec.samples = list(range(50))
      >>> spec.sorting = 2
      >>> spec.format  = 1
      >>> with segyio.create(path, spec) as f:
      ...     ## fill the file with data
      ...     pass
      ...
  
      Copy a file, but shorten all traces by 50 samples:
  
      >>> with segyio.open(srcpath) as src:
      ...     spec = segyio.spec()
      ...     spec.sorting = src.sorting
      ...     spec.format = src.format
      ...     spec.samples = src.samples[:len(src.samples) - 50]
      ...     spec.ilines = src.ilines
      ...     spec.xline = src.xlines
      ...     with segyio.create(dstpath, spec) as dst:
      ...         dst.text[0] = src.text[0]
      ...         dst.bin = src.bin
      ...         dst.header = src.header
      ...         dst.trace = src.trace
  
       Copy a file, but shift samples time by 50:
  
      >>> with segyio.open(srcpath) as src:
      ...     delrt = 50
      ...     spec = segyio.spec()
      ...     spec.samples = src.samples + delrt
      ...     spec.ilines = src.ilines
      ...     spec.xline = src.xlines
      ...     with segyio.create(dstpath, spec) as dst:
      ...         dst.text[0] = src.text[0]
      ...         dst.bin = src.bin
      ...         dst.header = src.header
      ...         dst.header = { TraceField.DelayRecordingTime: delrt }
      ...         dst.trace = src.trace
  
      Copy a file, but shorten all traces by 50 samples (since v1.4):
  
      >>> with segyio.open(srcpath) as src:
      ...     spec = segyio.tools.metadata(src)
      ...     spec.samples = spec.samples[:len(spec.samples) - 50]
      ...     with segyio.create(dstpath, spec) as dst:
      ...         dst.text[0] = src.text[0]
      ...         dst.bin = src.bin
      ...         dst.header = src.header
      ...         dst.trace = src.trace
      """; 26, relative_import; 27, dotted_name; 28, not_operator; 29, block; 30, else_clause; 31, assignment; 32, assignment; 33, assignment; 34, assignment; 35, comparison_operator:endian is None; 36, block; 37, comparison_operator:endian not in endians; 38, block; 39, assignment; 40, call; 41, assignment; 42, assignment; 43, call; 44, block; 45, assignment; 46, comparison_operator:len(samples) == 1; 47, block; 48, else_clause; 49, call; 50, identifier:f; 51, import_prefix; 52, identifier:_segyio; 53, call; 54, expression_statement; 55, block; 56, identifier:ext_headers; 57, conditional_expression:spec.ext_headers if hasattr(spec, 'ext_headers') else 0; 58, identifier:samples; 59, call; 60, identifier:endians; 61, dictionary; 62, identifier:endian; 63, conditional_expression:spec.endian if hasattr(spec, 'endian') else 'big'; 64, identifier:endian; 65, None; 66, expression_statement; 67, identifier:endian; 68, identifier:endians; 69, expression_statement; 70, expression_statement; 71, raise_statement; 72, identifier:fd; 73, call; 74, attribute; 75, argument_list; 76, identifier:f; 77, call; 78, attribute; 79, identifier:samples; 80, identifier:structured; 81, argument_list; 82, expression_statement; 83, if_statement; 84, expression_statement; 85, subscript; 86, call; 87, call; 88, integer:1; 89, expression_statement; 90, block; 91, attribute; 92, argument_list; 93, identifier:structured; 94, argument_list; 95, assignment; 96, expression_statement; 97, attribute; 98, call; 99, integer:0; 100, attribute; 101, argument_list; 102, pair; 103, comment:# (1 << 8); 104, pair; 105, pair; 106, pair; 107, attribute; 108, call; 109, string; 110, assignment; 111, assignment; 112, assignment; 113, call; 114, attribute; 115, argument_list; 116, identifier:fd; 117, identifier:segymake; 118, keyword_argument; 119, keyword_argument; 120, keyword_argument; 121, keyword_argument; 122, attribute; 123, argument_list; 124, identifier:f; 125, identifier:_samples; 126, identifier:spec; 127, assignment; 128, comparison_operator:sorting is None; 129, block; 130, call; 131, attribute; 132, integer:0; 133, identifier:default_text_header; 134, argument_list; 135, identifier:len; 136, argument_list; 137, assignment; 138, expression_statement; 139, attribute; 140, identifier:update; 141, keyword_argument; 142, keyword_argument; 143, keyword_argument; 144, keyword_argument; 145, keyword_argument; 146, keyword_argument; 147, keyword_argument; 148, keyword_argument; 149, identifier:spec; 150, identifier:tracecount; 151, attribute; 152, assignment; 153, identifier:spec; 154, identifier:ext_headers; 155, identifier:hasattr; 156, argument_list; 157, identifier:numpy; 158, identifier:asarray; 159, attribute; 160, string; 161, integer:256; 162, string; 163, integer:256; 164, string; 165, integer:0; 166, string; 167, integer:0; 168, identifier:spec; 169, identifier:endian; 170, identifier:hasattr; 171, argument_list; 172, string_content:big; 173, identifier:endian; 174, string; 175, identifier:problem; 176, string; 177, identifier:opts; 178, call; 179, identifier:ValueError; 180, argument_list; 181, identifier:_segyio; 182, identifier:segyiofd; 183, call; 184, string; 185, subscript; 186, identifier:samples; 187, call; 188, identifier:tracecount; 189, identifier:tracecount; 190, identifier:format; 191, call; 192, identifier:ext_headers; 193, call; 194, identifier:segyio; 195, identifier:SegyFile; 196, identifier:fd; 197, keyword_argument; 198, keyword_argument; 199, keyword_argument; 200, keyword_argument; 201, keyword_argument; 202, identifier:sorting; 203, conditional_expression:spec.sorting if hasattr(spec, 'sorting') else None; 204, identifier:sorting; 205, None; 206, expression_statement; 207, attribute; 208, argument_list; 209, identifier:f; 210, identifier:text; 211, attribute; 212, attribute; 213, attribute; 214, identifier:samples; 215, identifier:interval; 216, call; 217, assignment; 218, identifier:f; 219, identifier:bin; 220, identifier:ntrpr; 221, identifier:tracecount; 222, identifier:nart; 223, identifier:tracecount; 224, identifier:hdt; 225, identifier:interval; 226, identifier:dto; 227, identifier:interval; 228, identifier:hns; 229, call; 230, identifier:nso; 231, call; 232, identifier:format; 233, call; 234, identifier:exth; 235, identifier:ext_headers; 236, identifier:spec; 237, identifier:tracecount; 238, identifier:tracecount; 239, binary_operator:len(spec.ilines) * len(spec.xlines) * len(spec.offsets); 240, identifier:spec; 241, string; 242, identifier:spec; 243, identifier:samples; 244, string_content:lsb; 245, string_content:little; 246, string_content:msb; 247, string_content:big; 248, identifier:spec; 249, string; 250, string_content:big; 251, string_content:unknown endianness {}, expected one of:; 252, attribute; 253, argument_list; 254, binary_operator:problem.format(endian) + opts; 255, identifier:str; 256, argument_list; 257, string_content:w+; 258, identifier:endians; 259, identifier:endian; 260, identifier:len; 261, argument_list; 262, identifier:int; 263, argument_list; 264, identifier:int; 265, argument_list; 266, identifier:filename; 267, call; 268, identifier:mode; 269, string; 270, identifier:iline; 271, call; 272, identifier:xline; 273, call; 274, identifier:endian; 275, identifier:endian; 276, attribute; 277, call; 278, None; 279, assignment; 280, identifier:f; 281, identifier:interpret; 282, attribute; 283, attribute; 284, attribute; 285, identifier:sorting; 286, identifier:f; 287, identifier:_il; 288, identifier:f; 289, identifier:_xl; 290, attribute; 291, identifier:offset; 292, identifier:int; 293, argument_list; 294, identifier:interval; 295, call; 296, identifier:len; 297, argument_list; 298, identifier:len; 299, argument_list; 300, identifier:int; 301, argument_list; 302, binary_operator:len(spec.ilines) * len(spec.xlines); 303, call; 304, string_content:ext_headers; 305, string_content:endian; 306, string; 307, identifier:join; 308, call; 309, call; 310, identifier:opts; 311, identifier:filename; 312, identifier:samples; 313, attribute; 314, identifier:ext_headers; 315, identifier:str; 316, argument_list; 317, string_content:w+; 318, identifier:int; 319, argument_list; 320, identifier:int; 321, argument_list; 322, identifier:spec; 323, identifier:sorting; 324, identifier:hasattr; 325, argument_list; 326, identifier:sorting; 327, attribute; 328, identifier:spec; 329, identifier:ilines; 330, identifier:spec; 331, identifier:xlines; 332, identifier:spec; 333, identifier:offsets; 334, identifier:segyio; 335, identifier:TraceField; 336, binary_operator:samples[0] * 1000; 337, identifier:int; 338, argument_list; 339, identifier:samples; 340, identifier:samples; 341, attribute; 342, call; 343, call; 344, identifier:len; 345, argument_list; 346, string_content:; 347, attribute; 348, argument_list; 349, attribute; 350, argument_list; 351, identifier:spec; 352, identifier:format; 353, identifier:filename; 354, attribute; 355, attribute; 356, identifier:spec; 357, string; 358, identifier:TraceSortingFormat; 359, identifier:INLINE_SORTING; 360, subscript; 361, integer:1000; 362, binary_operator:(samples[1] - samples[0]) * 1000; 363, identifier:spec; 364, identifier:format; 365, identifier:len; 366, argument_list; 367, identifier:len; 368, argument_list; 369, attribute; 370, identifier:endians; 371, identifier:keys; 372, identifier:problem; 373, identifier:format; 374, identifier:endian; 375, identifier:spec; 376, identifier:iline; 377, identifier:spec; 378, identifier:xline; 379, string_content:sorting; 380, identifier:samples; 381, integer:0; 382, parenthesized_expression; 383, integer:1000; 384, attribute; 385, attribute; 386, identifier:spec; 387, identifier:offsets; 388, binary_operator:samples[1] - samples[0]; 389, identifier:spec; 390, identifier:ilines; 391, identifier:spec; 392, identifier:xlines; 393, subscript; 394, subscript; 395, identifier:samples; 396, integer:1; 397, identifier:samples; 398, integer:0
code: def create(filename, spec):
      """Create a new segy file.
  
      Create a new segy file with the geometry and properties given by `spec`.
      This enables creating SEGY files from your data. The created file supports
      all segyio modes, but has an emphasis on writing. The spec must be
      complete, otherwise an exception will be raised. A default, empty spec can
      be created with ``segyio.spec()``.
  
      Very little data is written to the file, so just calling create is not
      sufficient to re-read the file with segyio. Rather, every trace header and
      trace must be written to the file to be considered complete.
  
      Create should be used together with python's ``with`` statement. This ensure
      the data is written. Please refer to the examples.
  
      The ``segyio.spec()`` function will default sorting, offsets and everything
      in the mandatory group, except format and samples, and requires the caller
      to fill in *all* the fields in either of the exclusive groups.
  
      If any field is missing from the first exclusive group, and the tracecount
      is set, the resulting file will be considered unstructured. If the
      tracecount is set, and all fields of the first exclusive group are
      specified, the file is considered structured and the tracecount is inferred
      from the xlines/ilines/offsets. The offsets are defaulted to ``[1]`` by
      ``segyio.spec()``.
  
      Parameters
      ----------
      filename : str
          Path to file to create
      spec : segyio.spec
          Structure of the segy file
  
      Returns
      -------
      file : segyio.SegyFile
          An open segyio file handle, similar to that returned by `segyio.open`
  
      See also
      --------
      segyio.spec : template for the `spec` argument
  
  
      Notes
      -----
  
      .. versionadded:: 1.1
  
      .. versionchanged:: 1.4
         Support for creating unstructured files
  
      .. versionchanged:: 1.8
         Support for creating lsb files
  
      The ``spec`` is any object that has the following attributes
  
      Mandatory::
  
          iline   : int or segyio.BinField
          xline   : int or segyio.BinField
          samples : array of int
          format  : { 1, 5 }
              1 = IBM float, 5 = IEEE float
  
      Exclusive::
  
          ilines  : array_like of int
          xlines  : array_like of int
          offsets : array_like of int
          sorting : int or segyio.TraceSortingFormat
  
          OR
  
          tracecount : int
  
      Optional::
  
          ext_headers : int
          endian : str { 'big', 'msb', 'little', 'lsb' }
              defaults to 'big'
  
  
      Examples
      --------
  
      Create a file:
  
      >>> spec = segyio.spec()
      >>> spec.ilines  = [1, 2, 3, 4]
      >>> spec.xlines  = [11, 12, 13]
      >>> spec.samples = list(range(50))
      >>> spec.sorting = 2
      >>> spec.format  = 1
      >>> with segyio.create(path, spec) as f:
      ...     ## fill the file with data
      ...     pass
      ...
  
      Copy a file, but shorten all traces by 50 samples:
  
      >>> with segyio.open(srcpath) as src:
      ...     spec = segyio.spec()
      ...     spec.sorting = src.sorting
      ...     spec.format = src.format
      ...     spec.samples = src.samples[:len(src.samples) - 50]
      ...     spec.ilines = src.ilines
      ...     spec.xline = src.xlines
      ...     with segyio.create(dstpath, spec) as dst:
      ...         dst.text[0] = src.text[0]
      ...         dst.bin = src.bin
      ...         dst.header = src.header
      ...         dst.trace = src.trace
  
       Copy a file, but shift samples time by 50:
  
      >>> with segyio.open(srcpath) as src:
      ...     delrt = 50
      ...     spec = segyio.spec()
      ...     spec.samples = src.samples + delrt
      ...     spec.ilines = src.ilines
      ...     spec.xline = src.xlines
      ...     with segyio.create(dstpath, spec) as dst:
      ...         dst.text[0] = src.text[0]
      ...         dst.bin = src.bin
      ...         dst.header = src.header
      ...         dst.header = { TraceField.DelayRecordingTime: delrt }
      ...         dst.trace = src.trace
  
      Copy a file, but shorten all traces by 50 samples (since v1.4):
  
      >>> with segyio.open(srcpath) as src:
      ...     spec = segyio.tools.metadata(src)
      ...     spec.samples = spec.samples[:len(spec.samples) - 50]
      ...     with segyio.create(dstpath, spec) as dst:
      ...         dst.text[0] = src.text[0]
      ...         dst.bin = src.bin
      ...         dst.header = src.header
      ...         dst.trace = src.trace
      """
  
      from . import _segyio
  
      if not structured(spec):
          tracecount = spec.tracecount
      else:
          tracecount = len(spec.ilines) * len(spec.xlines) * len(spec.offsets)
  
      ext_headers = spec.ext_headers if hasattr(spec, 'ext_headers') else 0
      samples = numpy.asarray(spec.samples)
  
      endians = {
          'lsb': 256, # (1 << 8)
          'little': 256,
          'msb': 0,
          'big': 0,
      }
      endian = spec.endian if hasattr(spec, 'endian') else 'big'
      if endian is None:
          endian = 'big'
  
      if endian not in endians:
          problem = 'unknown endianness {}, expected one of: '
          opts = ' '.join(endians.keys())
          raise ValueError(problem.format(endian) + opts)
  
      fd = _segyio.segyiofd(str(filename), 'w+', endians[endian])
      fd.segymake(
          samples = len(samples),
          tracecount = tracecount,
          format = int(spec.format),
          ext_headers = int(ext_headers),
      )
  
      f = segyio.SegyFile(fd,
              filename = str(filename),
              mode = 'w+',
              iline = int(spec.iline),
              xline = int(spec.xline),
              endian = endian,
      )
  
      f._samples       = samples
  
      if structured(spec):
          sorting = spec.sorting if hasattr(spec, 'sorting') else None
          if sorting is None:
              sorting = TraceSortingFormat.INLINE_SORTING
          f.interpret(spec.ilines, spec.xlines, spec.offsets, sorting)
  
      f.text[0] = default_text_header(f._il, f._xl, segyio.TraceField.offset)
  
      if len(samples) == 1:
          interval = int(samples[0] * 1000)
      else:
          interval = int((samples[1] - samples[0]) * 1000)
  
      f.bin.update(
          ntrpr    = tracecount,
          nart     = tracecount,
          hdt      = interval,
          dto      = interval,
          hns      = len(samples),
          nso      = len(samples),
          format   = int(spec.format),
          exth     = ext_headers,
      )
  
      return f