def reconstruct(waveform, metadata, silence=False, manager=None):
        from neosound.sound import Sound

        if hasattr(waveform, "samplerate"):
            samplerate = waveform.samplerate
        else:
            samplerate = float(metadata["samplerate"]) * hertz

        if waveform is not None:
            sound = Sound(waveform, samplerate=samplerate, manager=manager)
        else:
            create = getattr(Sound, metadata["sound"])
            for kw in ["sound", "type"]:
                metadata.pop(kw)

            for kw, val in metadata.iteritems():
                if not kw.endswith("_units"):
                    if "%s_units" % kw in metadata:
                        val_units = metadata.pop("%s_units" % kw)
                        val_units = eval(re.subn("[a-z]+", lambda m: "units.%s" % m.group(), val_units)[0])
                        metadata[kw] = val * val_units

            create(manager=manager, **metadata)

        if silence:
            manager.logger.debug("Returning silence instead")
            return sound.to_silence()
        else:
            manager.logger.debug("Found waveform: returning")
            return sound
    def reconstruct(waveform, metadata, silence=False, manager=None):
        from neosound.sound import Sound

        if hasattr(waveform, "samplerate"):
            samplerate = waveform.samplerate
        else:
            samplerate = float(metadata["samplerate"]) * hertz

        if waveform is not None:
            sound = Sound(waveform, samplerate=samplerate, manager=manager)
        else:
            create = getattr(Sound, metadata["sound"])
            for kw in ["sound", "type"]:
                metadata.pop(kw)

            for kw, val in metadata.iteritems():
                if not kw.endswith("_units"):
                    if "%s_units" % kw in metadata:
                        val_units = metadata.pop("%s_units" % kw)
                        val_units = eval(
                            re.subn("[a-z]+", lambda m: "units.%s" % m.group(),
                                    val_units)[0])
                        metadata[kw] = val * val_units

            create(manager=manager, **metadata)

        if silence:
            manager.logger.debug("Returning silence instead")
            return sound.to_silence()
        else:
            manager.logger.debug("Found waveform: returning")
            return sound
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"] * hertz

        manager.logger.debug("Reconstructing mono transform")
        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)

        return sound.get_channel(metadata["channel"], read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"]*hertz

        manager.logger.debug("Reconstructing mono transform")
        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)

        return sound.get_channel(metadata["channel"], read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        manager.logger.debug("Reconstructing multiply transform")

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"] * hertz

        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)

        return sound.scale(metadata["coefficients"], read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        manager.logger.debug("Reconstructing multiply transform")

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"]*hertz

        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)

        return sound.scale(metadata["coefficients"], read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        manager.logger.debug("Reconstructing add transform")

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"] * hertz

        sound0 = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        sound1 = Sound(waveforms[1], samplerate=samplerate, manager=manager)

        return sound0.combine(sound1, read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        manager.logger.debug("Reconstructing add transform")

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"]*hertz

        sound0 = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        sound1 = Sound(waveforms[1], samplerate=samplerate, manager=manager)

        return sound0.combine(sound1, read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        manager.logger.debug("Reconstructing clip transform")

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"]*hertz

        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)

        return sound.clip(metadata["max_value"], metadata["min_value"],
                          read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = float(metadata["samplerate"]) * hertz

        manager.logger.debug("Reconstructing resample transform")
        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        new_samplerate = metadata["new_samplerate"]*hertz
        resample_type = metadata["resample_type"]

        return sound.resample(new_samplerate, resample_type=resample_type, read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"]*hertz

        manager.logger.debug("Reconstructing ramp transform")
        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        when = metadata["when"]
        duration = metadata["duration"]*second

        return sound.ramp(when=when, duration=duration, read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"] * hertz

        manager.logger.debug("Reconstructing ramp transform")
        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        when = metadata["when"]
        duration = metadata["duration"] * second

        return sound.ramp(when=when, duration=duration, read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        manager.logger.debug("Reconstructing slice transform")

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"] * hertz

        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        start = metadata["start_time"] * second
        stop = metadata["stop_time"] * second

        return sound.slice(start, stop, read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        manager.logger.debug("Reconstructing slice transform")

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"]*hertz

        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        start = metadata["start_time"]*second
        stop = metadata["stop_time"]*second

        return sound.slice(start, stop, read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        manager.logger.debug("Reconstructing clip transform")

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"] * hertz

        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)

        return sound.clip(metadata["max_value"],
                          metadata["min_value"],
                          read_only=True)
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = float(metadata["samplerate"]) * hertz

        manager.logger.debug("Reconstructing resample transform")
        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        new_samplerate = metadata["new_samplerate"] * hertz
        resample_type = metadata["resample_type"]

        return sound.resample(new_samplerate,
                              resample_type=resample_type,
                              read_only=True)
    def reconstruct(waveform, metadata, silence=False, manager=None):
        from neosound.sound import Sound

        if hasattr(waveform, "samplerate"):
            samplerate = waveform.samplerate
        else:
            samplerate = float(metadata["samplerate"]) * hertz

        if waveform is not None:
            sound = Sound(waveform, samplerate=samplerate, manager=manager)

        if silence:
            manager.logger.debug("Returning silence instead")
            return sound.to_silence()
        else:
            return sound
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"]*hertz

        manager.logger.debug("Reconstructing filter transform")
        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        frequency_range = [metadata["min_frequency"]*hertz,
                           metadata["max_frequency"]*hertz]

        return sound.filter(frequency_range,
                            filter_order=metadata["order"],
                            read_only=True)
    def reconstruct(waveform, metadata, silence=False, manager=None):
        from neosound.sound import Sound

        if hasattr(waveform, "samplerate"):
            samplerate = waveform.samplerate
        else:
            samplerate = float(metadata["samplerate"]) * hertz

        if waveform is not None:
            sound = Sound(waveform, samplerate=samplerate, manager=manager)

        if silence:
            manager.logger.debug("Returning silence instead")
            return sound.to_silence()
        else:
            return sound
    def reconstruct(waveforms, metadata, manager=None):
        from neosound.sound import Sound

        if hasattr(waveforms[0], "samplerate"):
            samplerate = waveforms[0].samplerate
        else:
            samplerate = metadata["samplerate"] * hertz

        manager.logger.debug("Reconstructing filter transform")
        sound = Sound(waveforms[0], samplerate=samplerate, manager=manager)
        frequency_range = [
            metadata["min_frequency"] * hertz,
            metadata["max_frequency"] * hertz
        ]

        return sound.filter(frequency_range,
                            filter_order=metadata["order"],
                            read_only=True)
        def get_waveform(id_):

            self.logger.debug("Attempting to get waveform for id %s" % id_)
            data = self.database.get_data(id_)
            if data is not None:
                samplerate = self.database.get_annotations(id_)["samplerate"]
                return Sound(data, samplerate=samplerate * hertz, manager=self)
            else:
                self.logger.debug("Attempting to get waveform from parents instead")
                metadata = self.database.get_metadata(id_)
                transform = metadata["type"]

                if ("parents" in metadata) and len(metadata["parents"]):
                    pids = metadata["parents"]
                    self.logger.debug("Attempting to reconstruct from %s parents" % len(pids))
                    return transform.reconstruct([get_waveform(pid) for pid in pids],
                                                 metadata,
                                                 manager=self)
                else:
                    self.logger.debug("parents not found in database for id %s. Attempting to reconstruct!" % id_)
                    waveform = self.database.get_data(id_)
                    return transform.reconstruct(waveform,
                                                 metadata,
                                                 manager=self)
    def reconstruct_individual(self, id_, root_id):
        from neosound.sound import Sound

        def get_waveform_ind(id_):
            self.logger.debug("Attempting to get waveform for id %s" % id_)

            metadata = self.database.get_metadata(id_)
            transform = metadata["type"]
            if ("parents" in metadata) and len(metadata["parents"]):
                pids = metadata["parents"]
                self.logger.debug("Attempting to reconstruct from %s parents" % len(pids))
                return transform.reconstruct([get_waveform_ind(pid) for pid in pids],
                                             metadata,
                                             manager=self)
            else:
                self.logger.debug("parents not found in database for id %s. Attempting to reconstruct!" % id_)
                # If this root id is not in root_ids, we want to replace the waveform with silence
                silence = id_ != root_id
                waveform = self.database.get_data(id_)
                return transform.reconstruct(waveform,
                                             metadata,
                                             silence,
                                             manager=self)

        roots = self.get_roots(id_)
        if root_id not in roots:
            self.logger.debug("Requested root_id not roots for id %s" % id_)
            return None

        component_id = self.database.filter_ids(transform_id=id_,
                                                transform_root_id=root_id)
        if len(component_id):

            component_id = component_id[0]
            data = self.database.get_data(component_id)
            if data is not None:
                samplerate = self.database.get_annotations(component_id)["samplerate"]
                sound = Sound(data, samplerate=samplerate*hertz, manager=self)
                sound.id = component_id
                sound.annotations.update(self.database.get_annotations(component_id))

                return sound
            else:
                store = True
                metadata = dict(type=ComponentTransform,
                                id=id_,
                                root_id=root_id,
                                parents=[id_, root_id])

        else:
            store = True
            metadata = dict(type=ComponentTransform,
                            id=id_,
                            root_id=root_id,
                            parents=[id_, root_id])

        sound = get_waveform_ind(id_)
        if store:
            self.store(sound, metadata)

        return sound