class asarray(asdtype): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__(type, "type", (asdtype.__metaclass__, ), {}) def __init__(self, fromdtype, toarray): if isinstance(fromdtype, awkward.util.numpy.dtype): self.fromdtype = fromdtype elif isinstance( fromdtype, string_types) and len(fromdtype) > 0 and fromdtype[0] in ( ">", "<", "=", "|", b">", b"<", b"=", b"|"): self.fromdtype = awkward.util.numpy.dtype(fromdtype) else: self.fromdtype = awkward.util.numpy.dtype(fromdtype).newbyteorder( ">") self.toarray = toarray @property def todtype(self): return awkward.util.numpy.dtype( (self.toarray.dtype, self.toarray.shape[1:])) def __repr__(self): return "asarray({0}, <array {1} {2} at 0x{3:012x}>)".format( repr(str(self.fromdtype)), self.toarray.dtype, self.toarray.shape, id(self.toarray)) @property def identifier(self): return "asarray" + super(asarray, self).identifier[7:] def destination(self, numitems, numentries): quotient, remainder = divmod(numitems, _flatlen(self.todtype)) if remainder != 0: raise ValueError( "cannot reshape {0} items as {1} (i.e. groups of {2})".format( numitems, self.todtype.shape, _flatlen(self.todtype))) if _flatlen(self.toarray) < numitems: raise ValueError( "cannot put {0} items into an array of {1} items".format( numitems, _flatlen(self.toarray))) return self.toarray, quotient def fill(self, source, destination, itemstart, itemstop, entrystart, entrystop): array, stop = destination super(asarray, self).fill(source, array, itemstart, itemstop, entrystart, entrystop) def clip(self, destination, itemstart, itemstop, entrystart, entrystop): array, stop = destination return super(asarray, self).clip(array, itemstart, itemstop, entrystart, entrystop), stop def finalize(self, destination, branch): array, stop = destination return array[:stop]
class asstlbitset(uproot.interp.interp.Interpretation): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__( type, "type", (uproot.interp.interp.Interpretation.__metaclass__, ), {}) todtype = awkward.util.numpy.dtype(awkward.util.numpy.bool_) def __init__(self, numbytes): self.numbytes = numbytes def __repr__(self): return self.identifier @property def identifier(self): return "asstlbitset({0})".format(self.numbytes) @property def type(self): return awkward.type.ArrayType(self.numbytes, self.todtype) def empty(self): return awkward.util.numpy.empty((0, self.numbytes), dtype=self.todtype) def compatible(self, other): return (isinstance(other, asstlbitset) and self.numbytes == other.numbytes) or \ (isinstance(other, (asdtype, asarray)) and self.todtype == other.todtype and (self.numbytes,) == other.todims) def numitems(self, numbytes, numentries): return max(0, numbytes // (self.numbytes + 4)) def source_numitems(self, source): return int(awkward.util.numpy.prod(source.shape)) def fromroot(self, data, byteoffsets, local_entrystart, local_entrystop): return data.view(self.todtype).reshape((-1, self.numbytes + 4))[:, 4:] def destination(self, numitems, numentries): return awkward.util.numpy.empty((numitems, self.numbytes), dtype=self.todtype) def fill(self, source, destination, itemstart, itemstop, entrystart, entrystop): destination[itemstart:itemstop] = source def clip(self, destination, itemstart, itemstop, entrystart, entrystop): return destination[itemstart:itemstop] def finalize(self, destination, branch): return destination
class asstring(_variable): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__(type, "type", (_variable.__metaclass__, ), {}) def __init__(self, skipbytes=1): super(asstring, self).__init__( uproot.interp.jagged.asjagged( uproot.interp.numerical.asdtype(awkward.util.CHARTYPE), skipbytes=skipbytes), lambda array: array.tostring()) def __repr__(self): return "asstring({0})".format("" if self.content.skipbytes == 1 else repr(self.content.skipbytes)) def compatible(self, other): return isinstance(other, asstring)
class asgenobj(_variable): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__(type, "type", (_variable.__metaclass__, ), {}) class _Wrapper(object): def __init__(self, cls, context): self.cls = cls self.context = context def __call__(self, bytes): source = uproot.source.source.Source(bytes) cursor = uproot.source.cursor.Cursor(0) return self.cls.read(source, cursor, self.context, None) def __repr__(self): if isinstance(self.cls, type): return self.cls.__name__ else: return repr(self.cls) def __init__(self, cls, context, skipbytes): super(asgenobj, self).__init__( uproot.interp.jagged.asjagged(uproot.interp.numerical.asdtype( awkward.util.CHARTYPE), skipbytes=skipbytes), asgenobj._Wrapper(cls, context)) def speedbump(self, value): out = copy.copy(self) out.generator = copy.copy(self.generator) out.generator.context = copy.copy(out.generator.context) out.generator.context.speedbump = value return out def __repr__(self): return "asgenobj({0})".format(self.generator)
class asobj(uproot.interp.interp.Interpretation): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__( type, "type", (uproot.interp.interp.Interpretation.__metaclass__, ), {}) def __init__(self, content, cls): self.content = content self.cls = cls @property def itemsize(self): return self.content.itemsize def __repr__(self): return "asobj(<{0}.{1}>)".format(self.cls.__module__, self.cls.__name__) @property def identifier(self): return "asobj({0},{1}.{2})".format(self.content.identifier, self.cls.__module__, self.cls.__name__) @property def type(self): return self.cls def empty(self): return self.content.empty() def compatible(self, other): return self.content.compatible(other) def numitems(self, numbytes, numentries): return self.content.numitems(numbytes, numentries) def source_numitems(self, source): return self.content.source_numitems(source) def fromroot(self, data, byteoffsets, local_entrystart, local_entrystop): return self.content.fromroot(data, byteoffsets, local_entrystart, local_entrystop) def destination(self, numitems, numentries): return self.content.destination(numitems, numentries) def fill(self, source, destination, itemstart, itemstop, entrystart, entrystop): return self.content.fill(source, destination, itemstart, itemstop, entrystart, entrystop) def clip(self, destination, itemstart, itemstop, entrystart, entrystop): return self.content.clip(destination, itemstart, itemstop, entrystart, entrystop) def finalize(self, destination, branch): if self.cls._arraymethods is None: return awkward.ObjectArray( self.content.finalize(destination, branch), self.cls._fromrow) else: cls = awkward.Methods.mixin(self.cls._arraymethods, awkward.ObjectArray) out = cls.__new__(cls) out._initObjectArray(self.content.finalize(destination, branch)) return out
class astable(uproot.interp.interp.Interpretation): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__( type, "type", (uproot.interp.interp.Interpretation.__metaclass__, ), {}) def __init__(self, content): if not isinstance(content, uproot.interp.numerical.asdtype ) or content.todtype.names is None or len( content.todtype.names) == 0: raise TypeError("astable must be given a recarray dtype") self.content = content @property def itemsize(self): return self.content.itemsize def __repr__(self): dtype, shape = uproot.interp.numerical._dtypeshape( self.content.todtype) return "astable({0})".format( repr( self.content.to( awkward.util.numpy.dtype([(n, dtype[n]) for n in dtype.names if not n.startswith(" ")]), shape))) def tonumpy(self): return self.content @property def identifier(self): dtype, shape = uproot.interp.numerical._dtypeshape( self.content.todtype) return "astable({0})".format( self.content.to( awkward.util.numpy.dtype([(n, dtype[n]) for n in dtype.names if not n.startswith(" ")]), shape).identifier) @property def type(self): dtype, shape = uproot.interp.numerical._dtypeshape( self.content.todtype) fields = None for n in dtype.names: if fields is None: fields = awkward.type.ArrayType(n, dtype[n]) else: fields = fields & awkward.type.ArrayType(n, dtype[n]) if shape == (): return fields else: return awkward.type.ArrayType(*(shape + (fields, ))) def empty(self): return awkward.Table.fromrec(self.content.empty()) def compatible(self, other): return isinstance(other, astable) and self.content.compatible( other.content) def numitems(self, numbytes, numentries): return self.content.numitems(numbytes, numentries) def source_numitems(self, source): return self.content.source_numitems(source) def fromroot(self, data, byteoffsets, local_entrystart, local_entrystop): return self.content.fromroot(data, byteoffsets, local_entrystart, local_entrystop) def destination(self, numitems, numentries): return self.content.destination(numitems, numentries) def fill(self, source, destination, itemstart, itemstop, entrystart, entrystop): return self.content.fill(source, destination, itemstart, itemstop, entrystart, entrystop) def clip(self, destination, itemstart, itemstop, entrystart, entrystop): return self.content.clip(destination, itemstart, itemstop, entrystart, entrystop) def finalize(self, destination, branch): return awkward.Table.fromrec(self.content.finalize( destination, branch))
class asdouble32(_asnumeric): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__(type, "type", (_asnumeric.__metaclass__, ), {}) def __init__(self, low, high, numbits, fromdims=(), todims=None): if not isinstance(numbits, numbers.Integral) or not 2 <= numbits <= 32: raise TypeError( "numbits must be an integer between 2 and 32 (inclusive)") if low == 0.0 and high == 0.0: raise NotImplementedError( "Double32_t with dropped mantissa bits not yet implemented") if high <= low: raise ValueError( "high ({0}) must be strictly greater than low ({1})".format( high, low)) self.low = low self.high = high self.numbits = numbits self.fromdims = fromdims if todims is None: self._todims = todims else: self._todims = fromdims @property def todtype(self): return awkward.util.numpy.dtype( (awkward.util.numpy.float64, self.todims)) @property def todtypeflat(self): return awkward.util.numpy.dtype(awkward.util.numpy.float64) @property def todims(self): return self._todims @property def itemsize(self): return 4 def __repr__(self): args = [repr(self.low), repr(self.high), repr(self.numbits)] if self.fromdims != (): args.append(repr(self.fromdims)) if self.todims != self.fromdims: args.append(repr(self.todims)) return "asdouble32(" + ", ".join(args) + ")" @property def identifier(self): fromdims = "(" + ",".join(repr(x) for x in self.fromdims) + ")" todims = "(" + ",".join(repr(x) for x in self.todims) + ")" return "asdouble32({0},{1},{2},{3},{4})".format( self.low, self.high, self.numbits, fromdims, todims) def compatible(self, other): return isinstance( other, asdouble32 ) and self.low == other.low and self.high == other.high and self.numbits == other.numbits and self.todtype == other.dtype def numitems(self, numbytes, numentries): quotient, remainder = divmod(numbytes, 4) assert remainder == 0 return quotient def fromroot(self, data, byteoffsets, local_entrystart, local_entrystop): array = data.view(">u4") if self.fromdims != (): product = int(awkward.util.numpy.prod(self.fromdims)) quotient, remainder = divmod(len(array), product) assert remainder == 0, "{0} % {1} == {2} != 0".format( len(array), product, len(array) % product) array = array.reshape((quotient, ) + self.fromdims) array = array[local_entrystart:local_entrystop].astype(self.todtype) awkward.util.numpy.multiply(array, float(self.high - self.low) / (1 << self.numbits), out=array) awkward.util.numpy.add(array, self.low, out=array) return array
class asdtype(_asnumeric): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__(type, "type", (_asnumeric.__metaclass__, ), {}) def __init__(self, fromdtype, todtype=None): if isinstance(fromdtype, awkward.util.numpy.dtype): self.fromdtype = fromdtype elif isinstance( fromdtype, string_types) and len(fromdtype) > 0 and fromdtype[0] in ( ">", "<", "=", "|", b">", b"<", b"=", b"|"): self.fromdtype = awkward.util.numpy.dtype(fromdtype) else: self.fromdtype = awkward.util.numpy.dtype(fromdtype).newbyteorder( ">") if todtype is None: self.todtype = self.fromdtype.newbyteorder("=") elif isinstance(todtype, awkward.util.numpy.dtype): self.todtype = todtype elif isinstance(todtype, string_types) and len(todtype) > 0 and todtype[0] in ( ">", "<", "=", "|", b">", b"<", b"=", b"|"): self.todtype = awkward.util.numpy.dtype(todtype) else: self.todtype = awkward.util.numpy.dtype(todtype).newbyteorder("=") @property def itemsize(self): return self.fromdtype.itemsize def to(self, todtype=None, todims=None): if todtype is None: dtype, shape = _dtypeshape(self.todtype) if todims is not None: shape = todims else: dtype, shape = _dtypeshape(todtype) if todims is not None: shape = todims + shape return asdtype(self.fromdtype, awkward.util.numpy.dtype( (dtype, shape))) def toarray(self, array): return asarray(self.fromdtype, array) def __repr__(self): args = [repr(str(self.fromdtype))] if self.fromdtype.newbyteorder(">") != self.todtype.newbyteorder(">"): args.append(repr(str(self.todtype))) return "asdtype({0})".format(", ".join(args)) @property def identifier(self): _byteorder = { "!": "B", ">": "B", "<": "L", "|": "L", "=": "B" if awkward.util.numpy.dtype(">f8").isnative else "L" } dtype, shape = _dtypeshape(self.fromdtype) fromdtype = "{0}{1}{2}({3})".format(_byteorder[dtype.byteorder], dtype.kind, dtype.itemsize, ",".join(repr(x) for x in shape)) dtype, shape = _dtypeshape(self.todtype) todtype = "{0}{1}{2}({3})".format(_byteorder[dtype.byteorder], dtype.kind, dtype.itemsize, ",".join(repr(x) for x in shape)) return "asdtype({0},{1})".format(fromdtype, todtype) def compatible(self, other): return isinstance(other, asdtype) and self.todtype == other.todtype def numitems(self, numbytes, numentries): dtype, shape = _dtypeshape(self.fromdtype) quotient, remainder = divmod(numbytes, dtype.itemsize) assert remainder == 0 return quotient def fromroot(self, data, byteoffsets, local_entrystart, local_entrystop): dtype, shape = _dtypeshape(self.fromdtype) return data.view(dtype).reshape( (-1, ) + shape)[local_entrystart:local_entrystop]
class asjagged(uproot.interp.interp.Interpretation): # makes __doc__ attribute mutable before Python 3.3 __metaclass__ = type.__new__( type, "type", (uproot.interp.interp.Interpretation.__metaclass__, ), {}) def __init__(self, content, skipbytes=0): self.content = content self.skipbytes = skipbytes def __repr__(self): return "asjagged({0})".format(repr(self.content)) def to(self, todtype=None, todims=None, skipbytes=None): if skipbytes is None: skipbytes = self.skipbytes return asjagged(self.content.to(todtype, todims), skipbytes) @property def identifier(self): return "asjagged({0}{1})".format( repr(self.content), "" if self.skipbytes == 0 else ",{0}".format(self.skipbytes)) @property def type(self): return awkward.type.ArrayType(awkward.util.numpy.inf, self.content.type) def empty(self): return awkward.JaggedArray( awkward.util.numpy.empty(0, dtype=awkward.util.INDEXTYPE), awkward.util.numpy.empty(0, dtype=awkward.util.INDEXTYPE), self.content.empty()) def compatible(self, other): return isinstance(other, asjagged) and self.content.compatible( other.content) def numitems(self, numbytes, numentries): return self.content.numitems(numbytes - numentries * self.skipbytes, numentries) def source_numitems(self, source): return self.content.source_numitems(source.content) def fromroot(self, data, byteoffsets, local_entrystart, local_entrystop): if local_entrystart == local_entrystop: return awkward.JaggedArray.fromoffsets( [0], self.content.fromroot(data, None, local_entrystart, local_entrystop)) else: if self.skipbytes == 0: offsets = _destructive_divide(byteoffsets, self.content.itemsize) starts = offsets[local_entrystart:local_entrystop] stops = offsets[local_entrystart + 1:local_entrystop + 1] content = self.content.fromroot(data, None, starts[0], stops[-1]) return awkward.JaggedArray(starts, stops, content) else: bytestarts = byteoffsets[ local_entrystart:local_entrystop] + self.skipbytes bytestops = byteoffsets[local_entrystart + 1:local_entrystop + 1] mask = awkward.util.numpy.zeros(len(data), dtype=awkward.util.numpy.int8) mask[bytestarts[bytestarts < len(data)]] = 1 awkward.util.numpy.add.at(mask, bytestops[bytestops < len(data)], -1) awkward.util.numpy.cumsum(mask, out=mask) data = data[mask.view(awkward.util.numpy.bool_)] content = self.content.fromroot(data, None, 0, bytestops[-1]) itemsize = 1 sub = self.content while hasattr(sub, "content"): sub = sub.content if isinstance(sub, uproot.interp.numerical.asdtype): itemsize = sub.fromdtype.itemsize if isinstance(sub, uproot.interp.numerical.asstlbitset): itemsize = sub.numbytes + 4 counts = bytestops - bytestarts shift = math.log(itemsize, 2) if shift == round(shift): awkward.util.numpy.right_shift(counts, int(shift), out=counts) else: awkward.util.numpy.floor_divide(counts, itemsize, out=counts) offsets = awkward.util.numpy.empty( len(counts) + 1, awkward.util.INDEXTYPE) offsets[0] = 0 awkward.util.numpy.cumsum(counts, out=offsets[1:]) return awkward.JaggedArray(offsets[:-1], offsets[1:], content) def destination(self, numitems, numentries): content = self.content.destination(numitems, numentries) counts = awkward.util.numpy.empty(numentries, dtype=awkward.util.INDEXTYPE) return _JaggedArrayPrep(counts, content) def fill(self, source, destination, itemstart, itemstop, entrystart, entrystop): self.content.fill(source.content, destination.content, itemstart, itemstop, entrystart, entrystop) destination.counts[entrystart:entrystop] = source.stops - source.starts def clip(self, destination, itemstart, itemstop, entrystart, entrystop): destination.content = self.content.clip(destination.content, itemstart, itemstop, entrystart, entrystop) destination.counts = destination.counts[entrystart:entrystop] return destination def finalize(self, destination, branch): content = self.content.finalize(destination.content, branch) leafcount = None if len(branch._fLeaves) == 1: leafcount = branch._fLeaves[0]._fLeafCount out = awkward.Methods.maybemixin(type(content), awkward.JaggedArray).fromcounts( destination.counts, content) out.leafcount = leafcount return out