# Buggy code
def _validate_header(filename):
    """
    This method automatically detects whether the Gadget file is big/little endian
    and is not corrupt/invalid using the first 4 bytes in the file.  It returns a
    tuple of (Valid, endianswap) where Valid is a boolean that is true if the file
    is a Gadget binary file, and endianswap is the endianness character '>' or '<'.
    """
    try:
        f = open(filename, "rb")
    except IOError:
        try:
            f = open(filename + ".0")
        except IOError:
            return False, 1

    # First int32 is 256 for a Gadget2 binary file with SnapFormat=1,
    # 8 for a Gadget2 binary file with SnapFormat=2 file,
    # or the byte swapped equivalents (65536 and 134217728).
    # The int32 following the header (first 4+256 bytes) must equal this
    # number.
    try:
        (rhead,) = struct.unpack("<I", f.read(4))
    except struct.error:
        f.close()
        return False, 1
    # Use value to check endianness
    if rhead == 256:
        endianswap = "<"
    elif rhead == 65536:
        endianswap = ">"
    elif rhead in (8, 134217728):
        # This is only true for snapshot format 2
        # we do not currently support double precision
        # snap format 2 data
        f.close()
        return True, "f4"
    else:
        f.close()
        return False, 1
    # Read in particle number from header
    np0 = sum(struct.unpack(endianswap + "IIIIII", f.read(6 * 4)))
    # Read in size of position block. It should be 4 bytes per float,
    # with 3 coordinates (x,y,z) per particle. (12 bytes per particle)
    f.seek(4 + 256 + 4, 0)
    np1 = struct.unpack(endianswap + "I", f.read(4))[0] / (4 * 3)
    f.close()
    # Compare
    if np0 == np1:
        return True, "f4"
    elif np1 == 2 * np0:
        return True, "f8"
    else:
        return False, 1


# Traceback (TypeError)
Traceback (most recent call last):
File "./plot_solution.py", line 519, in <module>
pf.add_field(("gas", "density_squared"), function=_density_squared, units="g**2/cm**6")
File "/usr/local/lib/python2.7/dist-packages/yt/data_objects/static_output.py", line 1191, in add_field
self.index
File "/usr/local/lib/python2.7/dist-packages/yt/data_objects/static_output.py", line 504, in index
self, dataset_type=self.dataset_type)
File "/usr/local/lib/python2.7/dist-packages/yt/geometry/particle_geometry_handler.py", line 39, in __init__
super(ParticleIndex, self).__init__(ds, dataset_type)
File "/usr/local/lib/python2.7/dist-packages/yt/geometry/geometry_handler.py", line 50, in __init__
self._setup_geometry()
File "/usr/local/lib/python2.7/dist-packages/yt/geometry/particle_geometry_handler.py", line 50, in _setup_geometry
self._initialize_particle_handler()
File "/usr/local/lib/python2.7/dist-packages/yt/geometry/particle_geometry_handler.py", line 104, in _initialize_particle_handler
self._initialize_indices()
File "/usr/local/lib/python2.7/dist-packages/yt/geometry/particle_geometry_handler.py", line 134, in _initialize_indices
self.io._initialize_index(data_file, self.regions)
File "/usr/local/lib/python2.7/dist-packages/yt/frontends/gadget/io.py", line 351, in _initialize_index
data_file, count, 0, regions, DLE, DRE)
File "/usr/local/lib/python2.7/dist-packages/yt/frontends/gadget/io.py", line 334, in _get_morton_from_position
pp = np.fromfile(f, dtype=self._endian + self._float_type,
TypeError: cannot concatenate 'str' and 'int' objects

# Fixed code
def _validate_header(filename, header_size):
    """
    This method automatically detects whether the Gadget file is big/little endian
    and is not corrupt/invalid using the first 4 bytes in the file.  It returns a
    tuple of (Valid, endianswap) where Valid is a boolean that is true if the file
    is a Gadget binary file, and endianswap is the endianness character '>' or '<'.
    """
    try:
        f = open(filename, "rb")
    except IOError:
        try:
            f = open(filename + ".0")
        except IOError:
            return False, 1

    # First int32 is 256 for a Gadget2 binary file with SnapFormat=1,
    # 8 for a Gadget2 binary file with SnapFormat=2 file,
    # or the byte swapped equivalents.
    # The int32 following the header (first 4+256 bytes) must equal this
    # number.
    # Note that 256 is the Gadget2 standard value, but other value could be
    # set using the header_size argument.
    try:
        (rhead,) = struct.unpack("<I", f.read(4))
    except struct.error:
        f.close()
        return False, 1
    # Use value to check endianness
    if rhead == header_size:
        endianswap = "<"
    elif rhead == _byte_swap_32(header_size):
        endianswap = ">"
    elif rhead in (8, _byte_swap_32(8)):
        # This is only true for snapshot format 2
        # we do not currently support double precision
        # snap format 2 data
        f.close()
        return True, "f4"
    else:
        f.close()
        return False, 1
    # Read in particle number from header
    np0 = sum(struct.unpack(endianswap + "IIIIII", f.read(6 * 4)))
    # Read in size of position block. It should be 4 bytes per float,
    # with 3 coordinates (x,y,z) per particle. (12 bytes per particle)
    f.seek(4 + header_size + 4, 0)
    np1 = struct.unpack(endianswap + "I", f.read(4))[0] / (4 * 3)
    f.close()
    # Compare
    if np0 == np1:
        return True, "f4"
    elif np1 == 2 * np0:
        return True, "f8"
    else:
        return False, 1