Beispiel #1
0
def oxpytools_source(filepath, max_events=None):
    """
    Temporary function to return a "source" generator from a targetio file,
    only if oxpytools exists on this python interpreter.

    Parameters
    ----------
    filepath : string
        Filepath for the input targetio file
    max_events : int
        Maximum number of events to read

    Returns
    -------
    source : generator
        A generator that can be iterated over to obtain events, obtained from
        a targetio file.
    """

    # Check oxpytools is installed
    try:
        import importlib
        oxpytools_spec = importlib.util.find_spec("oxpytools")
        found = oxpytools_spec is not None
        if found:
            from oxpytools.io.targetio import targetio_event_source
            return targetio_event_source(filepath, max_events=max_events)
        else:
            raise RuntimeError()
    except RuntimeError:
        log.exception("oxpytools is not installed on this interpreter")
        raise
Beispiel #2
0
def integrator_switch(data, geom, params):
    """
    Integrator switch using params['integrator'] to dictate which integration
    is applied.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    geom : `ctapipe.io.CameraGeometry`
        geometry of the camera's pixels
    params : dict
        REQUIRED:

        params['integrator'] - Integration scheme

        params['integration_window'] - Integration window size and starting
        sample for this integration

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).

    Returns
    -------
    integrator : lambda
        function corresponding to the specified integrator
    """

    try:
        if 'integrator' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    switch = {
        'full_integration':
            lambda: full_integration(data),
        'simple_integration':
            lambda: simple_integration(data, params),
        'global_peak_integration':
            lambda: global_peak_integration(data, params),
        'local_peak_integration':
            lambda: local_peak_integration(data, params),
        'nb_peak_integration':
            lambda: nb_peak_integration(data, geom, params),
        }
    try:
        integrator = switch[params['integrator']]()
    except KeyError:
        log.exception("unknown integrator '{}'".format(params['integrator']))
        raise

    return integrator
Beispiel #3
0
    def read(self, max_events=None):
        """
        Read the file using the appropriate method depending on the file origin

        Parameters
        ----------
        max_events : int
            Maximum number of events to read

        Returns
        -------
        source : generator
            A generator that can be iterated over to obtain events
        """

        # Obtain relevent source
        switch = {
            'hessio':
                lambda: hessio_event_source(get_path(self.input_path),
                                            max_events=max_events),
            'targetio':
                lambda: oxpytools_source(self.input_path,
                                         max_events=max_events),
        }
        try:
            source = switch[self.origin]()
        except KeyError:
            log.exception("unknown file origin '{}'".format(self.origin))
            raise

        return source
Beispiel #4
0
 def _login(self, username=None, store_password=False):
     if username is None:
         if self.USERNAME == "":
             raise LoginError("If you do not pass a username to login(), you should configure a default one!")
         else:
             username = self.USERNAME
     # Get password from keyring or prompt
     password_from_keyring = keyring.get_password("astroquery:www.eso.org", username)
     if password_from_keyring is None:
         if system_tools.in_ipynb():
             log.warn("You may be using an ipython notebook:"
                      " the password form will appear in your terminal.")
         password = getpass.getpass("{0}, enter your ESO password:\n".format(username))
     else:
         password = password_from_keyring
     # Authenticate
     log.info("Authenticating {0} on www.eso.org...".format(username))
     # Do not cache pieces of the login process
     login_response = self._request("GET", "https://www.eso.org/sso/login", cache=False)
     login_result_response = self._activate_form(login_response,
                                                 form_index=-1,
                                                 inputs={'username': username,
                                                         'password': password})
     root = BeautifulSoup(login_result_response.content, 'html5lib')
     authenticated = not root.select('.error')
     if authenticated:
         log.info("Authentication successful!")
     else:
         log.exception("Authentication failed!")
     # When authenticated, save password in keyring if needed
     if authenticated and password_from_keyring is None and store_password:
         keyring.set_password("astroquery:www.eso.org", username, password)
     return authenticated
Beispiel #5
0
 def _login(self, username=None, store_password=False):
     if username is None:
         if self.USERNAME == "":
             raise LoginError("If you do not pass a username to login(), you should configure a default one!")
         else:
             username = self.USERNAME
     # Get password from keyring or prompt
     password_from_keyring = keyring.get_password("astroquery:www.eso.org", username)
     if password_from_keyring is None:
         if system_tools.in_ipynb():
             log.warn("You may be using an ipython notebook:"
                      " the password form will appear in your terminal.")
         password = getpass.getpass("{0}, enter your ESO password:\n".format(username))
     else:
         password = password_from_keyring
     # Authenticate
     log.info("Authenticating {0} on www.eso.org...".format(username))
     # Do not cache pieces of the login process
     login_response = self._request("GET", "https://www.eso.org/sso/login", cache=False)
     login_result_response = self._activate_form(login_response,
                                                 form_index=-1,
                                                 inputs={'username': username,
                                                         'password': password})
     root = BeautifulSoup(login_result_response.content, 'html5lib')
     authenticated = not root.select('.error')
     if authenticated:
         log.info("Authentication successful!")
     else:
         log.exception("Authentication failed!")
     # When authenticated, save password in keyring if needed
     if authenticated and password_from_keyring is None and store_password:
         keyring.set_password("astroquery:www.eso.org", username, password)
     return authenticated
Beispiel #6
0
def calibration_parser(origin):
    """
    Obtain the correct parser for your input file.

    Parameters
    ----------
    origin : str
        Origin of data file e.g. hessio

    Return
    ------
    parser : `astropy.utils.compat.argparse.ArgumentParser`
        Argparser for calibration arguments.
    ns : `argparse.Namespace`
        Namespace containing the correction for default values so they use
        a custom Action.
    """

    # Obtain relevent calibrator arguments
    switch = {
        'hessio':
            lambda: mc.calibration_arguments(),
        }
    try:
        parser, ns = switch[origin]()
    except KeyError:
        log.exception("no calibration created for data origin: '{}'"
                      .format(origin))
        raise

    return parser, ns
Beispiel #7
0
    def _login(self, username=None, store_password=False,
               reenter_password=False):
        """
        Login to the ESO User Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ESO Public Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """
        if username is None:
            if self.USERNAME == "":
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Get password from keyring or prompt
        if reenter_password is False:
            password_from_keyring = keyring.get_password(
                "astroquery:www.eso.org", username)
        else:
            password_from_keyring = None

        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warning("You may be using an ipython notebook:"
                            " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your ESO password:\n"
                                       .format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on www.eso.org...".format(username))
        # Do not cache pieces of the login process
        login_response = self._request("GET", "https://www.eso.org/sso/login",
                                       cache=False)
        # login form: method=post action=login [no id]
        login_result_response = self._activate_form(
            login_response, form_index=-1, inputs={'username': username,
                                                   'password': password})
        root = BeautifulSoup(login_result_response.content, 'html5lib')
        authenticated = not root.select('.error')
        if authenticated:
            log.info("Authentication successful!")
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:www.eso.org", username, password)
        return authenticated
Beispiel #8
0
    def _login(self, username=None, store_password=False,
               reenter_password=False):
        """
        Login to the LCO Archive.

        Parameters
        ----------
        username : str, optional
            Username to the Las Cumbres Observatory archive. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored password
            on the keyring. Default is False.
        """
        if username is None:
            if self.USERNAME == "":
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Get password from keyring or prompt
        if reenter_password is False:
            password_from_keyring = keyring.get_password(
                "astroquery:archive-api.lco.global", username)
        else:
            password_from_keyring = None

        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warning("You may be using an ipython notebook:"
                            " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your Las Cumbres Observatory password:\n"
                                       .format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} with lco.global...".format(username))
        # Do not cache pieces of the login process
        login_response = self._request("POST", conf.get_token,
                                       cache=False, data={'username': username,
                                                          'password': password})
        # login form: method=post action=login [no id]

        if login_response.status_code == 200:
            log.info("Authentication successful!")
            token = json.loads(login_response.content)
            self.TOKEN = token['token']
        else:
            log.exception("Authentication failed!")
            token = None
        # When authenticated, save password in keyring if needed
        if token and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:archive-api.lco.global", username, password)
        return
Beispiel #9
0
    def _login(self, username=None, store_password=False,
               reenter_password=False):
        """
        Login to the ESO User Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ESO Public Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """
        if username is None:
            if self.USERNAME == "":
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Get password from keyring or prompt
        if reenter_password is False:
            password_from_keyring = keyring.get_password(
                "astroquery:www.eso.org", username)
        else:
            password_from_keyring = None

        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warning("You may be using an ipython notebook:"
                            " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your ESO password:\n"
                                       .format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on www.eso.org...".format(username))
        # Do not cache pieces of the login process
        login_response = self._request("GET", "https://www.eso.org/sso/login",
                                       cache=False)
        # login form: method=post action=login [no id]
        login_result_response = self._activate_form(
            login_response, form_index=-1, inputs={'username': username,
                                                   'password': password})
        root = BeautifulSoup(login_result_response.content, 'html5lib')
        authenticated = not root.select('.error')
        if authenticated:
            log.info("Authentication successful!")
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:www.eso.org", username, password)
        return authenticated
Beispiel #10
0
def integrator_switch(data, geom, params):
    """
    Integrator switch using params['integrator'] to dictate which integration
    is applied.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    geom : `ctapipe.io.CameraGeometry`
        geometry of the camera's pixels
    params : dict
        REQUIRED:

        params['integrator'] - Integration scheme

        params['integration_window'] - Integration window size and starting
        sample for this integration

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).

    Returns
    -------
    integrator : lambda
        function corresponding to the specified integrator
    """

    try:
        if 'integrator' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    switch = {
        'full_integration': lambda: full_integration(data),
        'simple_integration': lambda: simple_integration(data, params),
        'global_peak_integration':
        lambda: global_peak_integration(data, params),
        'local_peak_integration': lambda: local_peak_integration(data, params),
        'nb_peak_integration': lambda: nb_peak_integration(data, geom, params),
    }
    try:
        integrator = switch[params['integrator']]()
    except KeyError:
        log.exception("unknown integrator '{}'".format(params['integrator']))
        raise

    return integrator
Beispiel #11
0
    def read(self,
             allowed_tels=None,
             requested_event=None,
             use_event_id=False):
        """
        Read the file using the appropriate method depending on the file origin

        Parameters
        ----------
        allowed_tels : list[int]
            select only a subset of telescope, if None, all are read. This can
            be used for example emulate the final CTA data format, where there
            would be 1 telescope per file (whereas in current monte-carlo,
            they are all interleaved into one file)
        requested_event : int
            Seek to a paricular event index
        use_event_id : bool
            If True ,'requested_event' now seeks for a particular event id
            instead of index

        Returns
        -------
        source : generator
            A generator that can be iterated over to obtain events
        """

        # Obtain relevent source
        log.debug("[file] Reading file...")
        if self._max_events:
            log.info("[file] Max events being read = {}".format(
                self._max_events))
        switch = {
            'hessio':
            lambda: hessio_event_source(get_path(self.input_path),
                                        max_events=self._max_events,
                                        allowed_tels=allowed_tels,
                                        requested_event=requested_event,
                                        use_event_id=use_event_id),
            'targetio':
            lambda: targetio_source(self.input_path,
                                    max_events=self._max_events,
                                    allowed_tels=allowed_tels,
                                    requested_event=requested_event,
                                    use_event_id=use_event_id),
        }
        try:
            source = switch[self.origin]()
        except KeyError:
            log.exception("unknown file origin '{}'".format(self.origin))
            raise
        log.debug("[file] Reading complete")

        return source
Beispiel #12
0
    def input_path(self, string):
        path = Path(string)
        try:
            if not path.exists():
                raise FileNotFoundError
        except FileNotFoundError:
            log.exception("file path does not exist: '{}'".format(string))

        self.__input_path = path.as_posix()
        self.directory = dirname(self.__input_path)
        self.filename = splitext(basename(self.__input_path))[0]
        self.extension = splitext(self.__input_path)[1]
        self.output_directory = join(self.directory, self.filename)
Beispiel #13
0
    def input_path(self, string):
        path = Path(string)
        try:
            if not path.exists():
                raise FileNotFoundError
        except FileNotFoundError:
            log.exception("file path does not exist: '{}'".format(string))

        self.__input_path = path.as_posix()
        self.directory = dirname(self.__input_path)
        self.filename = splitext(basename(self.__input_path))[0]
        self.extension = splitext(self.__input_path)[1]
        self.output_directory = join(self.directory, self.filename)
Beispiel #14
0
    def read(self, allowed_tels=None, requested_event=None,
             use_event_id=False):
        """
        Read the file using the appropriate method depending on the file origin

        Parameters
        ----------
        allowed_tels : list[int]
            select only a subset of telescope, if None, all are read. This can
            be used for example emulate the final CTA data format, where there
            would be 1 telescope per file (whereas in current monte-carlo,
            they are all interleaved into one file)
        requested_event : int
            Seek to a paricular event index
        use_event_id : bool
            If True ,'requested_event' now seeks for a particular event id
            instead of index

        Returns
        -------
        source : generator
            A generator that can be iterated over to obtain events
        """

        # Obtain relevent source
        log.debug("[file] Reading file...")
        if self._max_events:
            log.info("[file] Max events being read = {}"
                     .format(self._max_events))
        switch = {
            'hessio':
                lambda: hessio_event_source(get_path(self.input_path),
                                            max_events=self._max_events,
                                            allowed_tels=allowed_tels,
                                            requested_event=requested_event,
                                            use_event_id=use_event_id),
            'targetio':
                lambda: targetio_source(self.input_path,
                                        max_events=self._max_events,
                                        allowed_tels=allowed_tels,
                                        requested_event=requested_event,
                                        use_event_id=use_event_id),
        }
        try:
            source = switch[self.origin]()
        except KeyError:
            log.exception("unknown file origin '{}'".format(self.origin))
            raise
        log.debug("[file] Reading complete")

        return source
Beispiel #15
0
    def guesspeakwidth(self,event,debug=False,nwidths=1,**kwargs):
        """
        Interactively guess the peak height and width from user input

        Width is assumed to be half-width-half-max
        """
        modnum = 1+nwidths
        if debug or self._debug: print("nclicks: %i nwidths: %i modnum: %i" % (self.nclicks_b2,nwidths,modnum))
        if self.nclicks_b2 == 0:
            self.firstclick_guess()
        if self.nclicks_b2 % modnum == 0:
            # even clicks are peaks
            if self.Spectrum.baseline.subtracted:
                peakguess = event.ydata
            else:
                peakguess = event.ydata - self.Spectrum.baseline.basespec[self.Spectrum.xarr.x_to_pix(event.xdata)]
            self.guesses += [peakguess,event.xdata] + [1]*nwidths
            self.npeaks += 1
            self.nclicks_b2 += 1
            if debug or self._debug:
                print("Peak %i click %i at x,y %g,%g" % (self.npeaks,self.nclicks_b2,event.xdata,event.ydata))
            self.button2plot += [self.Spectrum.plotter.axis.scatter(event.xdata,event.ydata,marker='x',c='r')]
            #self.Spectrum.plotter.refresh() #plot(**self.Spectrum.plotter.plotkwargs)
        elif self.nclicks_b2 % modnum >= 1:
            # odd clicks are widths
            whichwidth = self.nclicks_b2 % modnum
            widthguess = (abs(event.xdata-self.guesses[-1-nwidths]) /
                          numpy.sqrt(2*numpy.log(2)))
            if numpy.isnan(widthguess) or widthguess <= 0:
                newwidthguess = numpy.abs(self.Spectrum.xarr.diff()).min().value
                if newwidthguess <= 0:
                    raise ValueError("A width guess could not be determined.")
                log.exception("Error: width guess was {0}.  It is being forced to {1}."
                              .format(widthguess, newwidthguess))
                widthguess = newwidthguess
            self.guesses[-whichwidth] = widthguess
            if debug or self._debug:
                print("Width %i whichwidth %i click %i at x,y %g,%g width: %g" % (self.npeaks,whichwidth,self.nclicks_b2,event.xdata,event.ydata,self.guesses[-whichwidth]))
            self.button2plot += self.Spectrum.plotter.axis.plot([event.xdata,
                                                                 2*self.guesses[-1-nwidths]-event.xdata],
                                                                [event.ydata]*2,
                                                                color='r')
            #self.Spectrum.plotter.refresh() #plot(**self.Spectrum.plotter.plotkwargs)
            if self.nclicks_b2 / (1+nwidths) > self.npeaks:
                print("There have been %i middle-clicks but there are only %i features" % (self.nclicks_b2,self.npeaks))
                self.npeaks += 1
            self.nclicks_b2 += 1
        else:
            raise ValueError("Bug in guesspeakwidth: somehow, the number of clicks doesn't make sense.")
        if debug or self._debug:
            print("Guesses: ",self.guesses)
Beispiel #16
0
    def guesspeakwidth(self,event,debug=False,nwidths=1,**kwargs):
        """
        Interactively guess the peak height and width from user input

        Width is assumed to be half-width-half-max
        """
        modnum = 1+nwidths
        if debug or self._debug: print("nclicks: %i nwidths: %i modnum: %i" % (self.nclicks_b2,nwidths,modnum))
        if self.nclicks_b2 == 0:
            self.firstclick_guess()
        if self.nclicks_b2 % modnum == 0:
            # even clicks are peaks
            if self.Spectrum.baseline.subtracted:
                peakguess = event.ydata
            else:
                peakguess = event.ydata - self.Spectrum.baseline.basespec[self.Spectrum.xarr.x_to_pix(event.xdata)]
            self.guesses += [peakguess,event.xdata] + [1]*nwidths
            self.npeaks += 1
            self.nclicks_b2 += 1
            if debug or self._debug:
                print("Peak %i click %i at x,y %g,%g" % (self.npeaks,self.nclicks_b2,event.xdata,event.ydata))
            self.button2plot += [self.Spectrum.plotter.axis.scatter(event.xdata,event.ydata,marker='x',c='r')]
            #self.Spectrum.plotter.refresh() #plot(**self.Spectrum.plotter.plotkwargs)
        elif self.nclicks_b2 % modnum >= 1:
            # odd clicks are widths
            whichwidth = self.nclicks_b2 % modnum
            widthguess = (abs(event.xdata-self.guesses[-1-nwidths]) /
                          numpy.sqrt(2*numpy.log(2)))
            if numpy.isnan(widthguess) or widthguess <= 0:
                newwidthguess = numpy.abs(self.Spectrum.xarr.diff()).min().value
                if newwidthguess <= 0:
                    raise ValueError("A width guess could not be determined.")
                log.exception("Error: width guess was {0}.  It is being forced to {1}."
                              .format(widthguess, newwidthguess))
                widthguess = newwidthguess
            self.guesses[-whichwidth] = widthguess
            if debug or self._debug:
                print("Width %i whichwidth %i click %i at x,y %g,%g width: %g" % (self.npeaks,whichwidth,self.nclicks_b2,event.xdata,event.ydata,self.guesses[-whichwidth]))
            self.button2plot += self.Spectrum.plotter.axis.plot([event.xdata,
                                                                 2*self.guesses[-1-nwidths]-event.xdata],
                                                                [event.ydata]*2,
                                                                color='r')
            #self.Spectrum.plotter.refresh() #plot(**self.Spectrum.plotter.plotkwargs)
            if self.nclicks_b2 / (1+nwidths) > self.npeaks:
                print("There have been %i middle-clicks but there are only %i features" % (self.nclicks_b2,self.npeaks))
                self.npeaks += 1
            self.nclicks_b2 += 1
        else:
            raise ValueError("Bug in guesspeakwidth: somehow, the number of clicks doesn't make sense.")
        if debug or self._debug:
            print("Guesses: ",self.guesses)
Beispiel #17
0
    def _login(self, username, store_password=False):
        # Check if already logged in
        loginpage = self._request("GET",
                                  "https://asa.alma.cl/cas/login",
                                  cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        # Get password from keyring or prompt
        password_from_keyring = keyring.get_password("astroquery:asa.alma.cl",
                                                     username)
        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warn("You may be using an ipython notebook:"
                         " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your ALMA password:"******"\n".format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on asa.alma.cl ...".format(username))
        # Do not cache pieces of the login process
        data = {
            kw: root.find('input', {'name': kw})['value']
            for kw in ('lt', '_eventId', 'execution')
        }
        data['username'] = username
        data['password'] = password

        login_response = self._request(
            "POST",
            "https://asa.alma.cl/cas/login",
            params={'service': urljoin(self.archive_url, 'rh/login')},
            data=data,
            cache=False)

        authenticated = ('You have successfully logged in'
                         in login_response.text)

        if authenticated:
            log.info("Authentication successful!")
            self._username = username
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:asa.alma.cl", username, password)
        return authenticated
Beispiel #18
0
    def _parse_response(self, request_payload, cache):
        if not self.TOKEN:
            warnings.warn("You have not authenticated and will only get results for non-proprietary data")
            headers=None
        else:
            headers = {'Authorization': 'Token ' + self.TOKEN}

        response = self._request('GET', self.FRAMES_URL, params=request_payload,
                                 timeout=self.TIMEOUT, cache=cache, headers=headers)
        if response.status_code == 200:
            resp = json.loads(response.content)
            return self._parse_result(resp)
        else:
            log.exception("Failed!")
            return False
Beispiel #19
0
def targetio_source(filepath,
                    max_events=None,
                    allowed_tels=None,
                    requested_event=None,
                    use_event_id=False):
    """
    Temporary function to return a "source" generator from a targetio file,
    only if targetpipe exists on this python interpreter.

    Parameters
    ----------
    filepath : string
        Filepath for the input targetio file
    max_events : int
        Maximum number of events to read
    allowed_tels : list[int]
        select only a subset of telescope, if None, all are read.
    requested_event : int
        Seek to a paricular event index
    use_event_id : bool
        If True ,'requested_event' now seeks for a particular event id instead
        of index

    Returns
    -------
    source : generator
        A generator that can be iterated over to obtain events, obtained from
        a targetio file.
    """

    # Check targetpipe is installed
    try:
        import importlib
        targetpipe_spec = importlib.util.find_spec("targetpipe")
        found = targetpipe_spec is not None
        if found:
            from targetpipe.io.targetio import targetio_event_source
            return targetio_event_source(filepath,
                                         max_events=max_events,
                                         allowed_tels=allowed_tels,
                                         requested_event=requested_event,
                                         use_event_id=use_event_id)
        else:
            raise RuntimeError()
    except RuntimeError:
        log.exception("targetpipe is not installed on this interpreter")
        raise
Beispiel #20
0
    def _login(self, username, store_password=False):
        # Check if already logged in
        loginpage = self._request("GET", "https://asa.alma.cl/cas/login",
                                  cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        # Get password from keyring or prompt
        password_from_keyring = keyring.get_password("astroquery:asa.alma.cl",
                                                     username)
        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warn("You may be using an ipython notebook:"
                         " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your ALMA password:"******"\n".format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on asa.alma.cl ...".format(username))
        # Do not cache pieces of the login process
        data = {kw: root.find('input', {'name': kw})['value']
                for kw in ('lt', '_eventId', 'execution')}
        data['username'] = username
        data['password'] = password

        login_response = self._request("POST", "https://asa.alma.cl/cas/login",
                                       params={'service':
                                               urljoin(self.archive_url,
                                                       'rh/login')},
                                       data=data,
                                       cache=False)

        authenticated = ('You have successfully logged in' in
                         login_response.content)

        if authenticated:
            log.info("Authentication successful!")
            self._username = username
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:asa.alma.cl", username, password)
        return authenticated
Beispiel #21
0
    def find_max_true_npe(self, telescopes=None, max_events=None):
        """
        Loop through events to find the maximum true npe

        Parameters
        ----------
        telescopes : list
            List of telecopes to include. If None, then all telescopes
            are included.
        max_events : int
            Maximum number of events to read

        Returns
        -------
        max_pe : int

        """
        log.info("[file][read] Finding maximum true npe inside file...")
        source = self.read(max_events)
        max_pe = 0
        for event in source:
            tels = list(event.dl0.tels_with_data)
            if telescopes is not None:
                tels = []
                for tel in telescopes:
                    if tel in event.dl0.tels_with_data:
                        tels.append(tel)
            if event.count == 0:
                # Check events have true charge included
                try:
                    if np.all(event.mc.tel[tels[0]].photo_electrons == 0):
                        raise KeyError
                except KeyError:
                    log.exception('[chargeres] Source does not contain '
                                  'true charge')
                    raise
            for telid in tels:
                pe = event.mc.tel[telid].photo_electrons
                this_max = np.max(pe)
                if this_max > max_pe:
                    max_pe = this_max
        log.info("[file] Maximum true npe = {}".format(max_pe))

        return max_pe
Beispiel #22
0
    def add_source(self, calibrated_source, telescopes=None):
        """
        Fill the class parameters with a calibrated source.

        Parameters
        ----------
        calibrated_source : ndarray
            `ctapipe.calib.camera.calibrators.calibrate_source` generator.
        telescopes : list
               List of telescopes to include into the charge resolution.
               If None, all telescopes will be included.
        """
        log.info('[chargeres] Adding source')
        for event in calibrated_source:
            tels = list(event.dl0.tels_with_data)
            if telescopes is not None:
                tels = []
                for tel in telescopes:
                    if tel in event.dl0.tels_with_data:
                        tels.append(tel)

            # Check source has required information
            if event.count == 0:
                # Check source is calibrated
                try:
                    if 'dl1' not in event:
                        raise KeyError
                except KeyError:
                    log.exception('[chargeres] Source has not been calibrated')
                    raise

                # Check events have true charge included
                try:
                    if np.all(event.mc.tel[tels[0]].photo_electrons == 0):
                        raise KeyError
                except KeyError:
                    log.exception('[chargeres] Source does not '
                                  'contain true charge')
                    raise

            for telid in tels:
                true_charge = event.mc.tel[telid].photo_electrons
                measured_charge = event.dl1.tel[telid].pe_charge
                self.add_charges(true_charge, measured_charge)
Beispiel #23
0
    def add_source(self, calibrated_source, telescopes=None):
        """
        Fill the class parameters with a calibrated source.

        Parameters
        ----------
        calibrated_source : ndarray
            `ctapipe.calib.camera.calibrators.calibrate_source` generator.
        telescopes : list
               List of telescopes to include into the charge resolution.
               If None, all telescopes will be included.
        """
        log.info('[chargeres] Adding source')
        for event in calibrated_source:
            tels = list(event.dl0.tels_with_data)
            if telescopes is not None:
                tels = []
                for tel in telescopes:
                    if tel in event.dl0.tels_with_data:
                        tels.append(tel)

            # Check source has required information
            if event.count == 0:
                # Check source is calibrated
                try:
                    if 'dl1' not in event:
                        raise KeyError
                except KeyError:
                    log.exception('[chargeres] Source has not been calibrated')
                    raise

                # Check events have true charge included
                try:
                    if np.all(event.mc.tel[tels[0]].photo_electrons == 0):
                        raise KeyError
                except KeyError:
                    log.exception('[chargeres] Source does not '
                                  'contain true charge')
                    raise

            for telid in tels:
                true_charge = event.mc.tel[telid].photo_electrons
                measured_charge = event.dl1.tel[telid].pe_charge
                self.add_charges(true_charge, measured_charge)
Beispiel #24
0
    def find_max_true_npe(self, telescopes=None, max_events=None):
        """
        Loop through events to find the maximum true npe

        Parameters
        ----------
        telescopes : list
            List of telecopes to include. If None, then all telescopes
            are included.
        max_events : int
            Maximum number of events to read

        Returns
        -------
        max_pe : int

        """
        log.info("[file][read] Finding maximum true npe inside file...")
        source = self.read(max_events)
        max_pe = 0
        for event in source:
            tels = list(event.dl0.tels_with_data)
            if telescopes is not None:
                tels = []
                for tel in telescopes:
                    if tel in event.dl0.tels_with_data:
                        tels.append(tel)
            if event.count == 0:
                # Check events have true charge included
                try:
                    if np.all(event.mc.tel[tels[0]].photo_electrons == 0):
                        raise KeyError
                except KeyError:
                    log.exception('[chargeres] Source does not contain '
                                  'true charge')
                    raise
            for telid in tels:
                pe = event.mc.tel[telid].photo_electrons
                this_max = np.max(pe)
                if this_max > max_pe:
                    max_pe = this_max
        log.info("[file] Maximum true npe = {}".format(max_pe))

        return max_pe
Beispiel #25
0
def targetio_source(filepath, max_events=None, allowed_tels=None,
                    requested_event=None, use_event_id=False):
    """
    Temporary function to return a "source" generator from a targetio file,
    only if targetpipe exists on this python interpreter.

    Parameters
    ----------
    filepath : string
        Filepath for the input targetio file
    max_events : int
        Maximum number of events to read
    allowed_tels : list[int]
        select only a subset of telescope, if None, all are read.
    requested_event : int
        Seek to a paricular event index
    use_event_id : bool
        If True ,'requested_event' now seeks for a particular event id instead
        of index

    Returns
    -------
    source : generator
        A generator that can be iterated over to obtain events, obtained from
        a targetio file.
    """

    # Check targetpipe is installed
    try:
        import importlib
        targetpipe_spec = importlib.util.find_spec("targetpipe")
        found = targetpipe_spec is not None
        if found:
            from targetpipe.io.targetio import targetio_event_source
            return targetio_event_source(filepath, max_events=max_events,
                                         allowed_tels=allowed_tels,
                                         requested_event=requested_event,
                                         use_event_id=use_event_id)
        else:
            raise RuntimeError()
    except RuntimeError:
        log.exception("targetpipe is not installed on this interpreter")
        raise
Beispiel #26
0
def calibration_parameters(args):
    """
    Parse you argpasers arguments for calibration parameters, and store them
    inside a dict.

    Parameters
    ----------
    args : `astropy.utils.compat.argparse.ArgumentParser.parse_args()`

    Returns
    -------
    parameters : dict
        dictionary containing the formatted calibration parameters
    """
    parameters = {}
    if args.integrator is not None:
        integrator_names, inverse = integrator_dict()
        try:
            parameters['integrator'] = integrator_names[args.integrator]
        except KeyError:
            log.exception(
                '[calib] Specified integrator does not exist: {}'.format(
                    args.integrator))
            raise
    if args.integration_window is not None:
        parameters['window'] = args.integration_window[0]
        parameters['shift'] = args.integration_window[1]
    if args.integration_sigamp is not None:
        parameters['sigamp'] = args.integration_sigamp[:2]
    if args.integration_clip_amp is not None:
        parameters['clip_amp'] = args.integration_clip_amp
    if args.integration_lwt is not None:
        parameters['lwt'] = args.integration_lwt
    if args.integration_calib_scale is not None:
        parameters['calib_scale'] = args.integration_calib_scale

    for key, value in parameters.items():
        log.info("[{}] {}".format(key, value))

    return parameters
Beispiel #27
0
def calibration_parameters(args):
    """
    Parse you argpasers arguments for calibration parameters, and store them
    inside a dict.

    Parameters
    ----------
    args : `astropy.utils.compat.argparse.ArgumentParser.parse_args()`

    Returns
    -------
    parameters : dict
        dictionary containing the formatted calibration parameters
    """
    parameters = {}
    if args.integrator is not None:
        integrator_names, inverse = integrator_dict()
        try:
            parameters['integrator'] = integrator_names[args.integrator]
        except KeyError:
            log.exception('[calib] Specified integrator does not exist: {}'
                          .format(args.integrator))
            raise
    if args.integration_window is not None:
        parameters['window'] = args.integration_window[0]
        parameters['shift'] = args.integration_window[1]
    if args.integration_sigamp is not None:
        parameters['sigamp'] = args.integration_sigamp[:2]
    if args.integration_clip_amp is not None:
        parameters['clip_amp'] = args.integration_clip_amp
    if args.integration_lwt is not None:
        parameters['lwt'] = args.integration_lwt
    if args.integration_calib_scale is not None:
        parameters['calib_scale'] = args.integration_calib_scale

    for key, value in parameters.items():
        log.info("[{}] {}".format(key, value))

    return parameters
Beispiel #28
0
                fn = fnt.format(spw)

                vcen = u.Quantity(vcen, u.km / u.s)

                #fn = '/Volumes/external/orion/full_OrionSourceI_B6_spw0_lines_cutout.fits'

                medsubfn = fn.replace(".image.pbcor.fits",
                                      "_medsub.image.pbcor.fits")

                if os.path.exists(medsubfn):
                    medsub = SpectralCube.read(medsubfn)
                    medsub.beam_threshold = 5000
                    if not medsub.wcs.wcs.radesys.lower() == 'icrs':
                        log.exception(
                            "Skipping {0} because of a bad coordinate system.".
                            format(medsubfn))
                        continue

                else:
                    #cube = (SpectralCube.read(fn)[:,515:721,550:714].mask_out_bad_beams(5))
                    cube = (SpectralCube.read(fn).mask_out_bad_beams(5))
                    if not cube.wcs.wcs.radesys.lower() == 'icrs':
                        log.exception(
                            "Skipping {0} because of a bad coordinate system.".
                            format(fn))
                        continue
                    # cube.allow_huge_operations=True
                    cube.beam_threshold = 5000
                    log.info("Calculating 25th percentile")
                    med = cube.percentile(25, axis=0)
Beispiel #29
0
    def _login(self,
               username=None,
               store_password=False,
               reenter_password=False,
               auth_urls=['asa.alma.cl', 'rh-cas.alma.cl']):
        """
        Login to the ALMA Science Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ALMA Science Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """

        if username is None:
            if not self.USERNAME:
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        success = False
        for auth_url in auth_urls:
            # set session cookies (they do not get set otherwise)
            cookiesetpage = self._request("GET",
                                          urljoin(self._get_dataarchive_url(),
                                                  'rh/forceAuthentication'),
                                          cache=False)
            self._login_cookiepage = cookiesetpage
            cookiesetpage.raise_for_status()

            if (auth_url + '/cas/login' in cookiesetpage.request.url):
                # we've hit a target, we're good
                success = True
                break
        if not success:
            raise LoginError("Could not log in to any of the known ALMA "
                             "authorization portals: {0}".format(auth_urls))

        # Check if already logged in
        loginpage = self._request(
            "GET",
            "https://{auth_url}/cas/login".format(auth_url=auth_url),
            cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        # Get password from keyring or prompt
        password, password_from_keyring = self._get_password(
            "astroquery:{0}".format(auth_url),
            username,
            reenter=reenter_password)

        # Authenticate
        log.info("Authenticating {0} on {1} ...".format(username, auth_url))
        # Do not cache pieces of the login process
        data = {
            kw: root.find('input', {'name': kw})['value']
            for kw in ('lt', '_eventId', 'execution')
        }
        data['username'] = username
        data['password'] = password
        data['submit'] = 'LOGIN'

        login_response = self._request(
            "POST",
            "https://{0}/cas/login".format(auth_url),
            params={'service': self._get_dataarchive_url()},
            data=data,
            cache=False)

        # save the login response for debugging purposes
        self._login_response = login_response
        # do not expose password back to user
        del data['password']
        # but save the parameters for debug purposes
        self._login_parameters = data

        authenticated = ('You have successfully logged in'
                         in login_response.text)

        if authenticated:
            log.info("Authentication successful!")
            self.USERNAME = username
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:{0}".format(auth_url), username,
                                 password)
        return authenticated
Beispiel #30
0
    def _login(self, username=None, store_password=False,
               reenter_password=False):
        """
        Login to the NRAO archive

        Parameters
        ----------
        username : str, optional
            Username to the NRAO archive. If not given, it should be specified
            in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """

        # Developer notes:
        # Login via https://my.nrao.edu/cas/login
        # # this can be added to auto-redirect back to the query tool:
        # ?service=https://archive.nrao.edu/archive/advquery.jsp

        if username is None:
            if not self.USERNAME:
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Check if already logged in
        loginpage = self._request("GET", "https://my.nrao.edu/cas/login",
                                  cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        # Get password from keyring or prompt
        if reenter_password is False:
            password_from_keyring = keyring.get_password(
                "astroquery:my.nrao.edu", username)
        else:
            password_from_keyring = None

        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warning("You may be using an ipython notebook:"
                            " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your NRAO archive password:"******"\n".format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on my.nrao.edu ...".format(username))
        # Do not cache pieces of the login process
        data = {kw: root.find('input', {'name': kw})['value']
                for kw in ('lt', '_eventId', 'execution')}
        data['username'] = username
        data['password'] = password
        data['execution'] = 'e1s1'  # not sure if needed
        data['_eventId'] = 'submit'
        data['submit'] = 'LOGIN'

        login_response = self._request("POST", "https://my.nrao.edu/cas/login",
                                       data=data, cache=False)

        authenticated = ('You have successfully logged in' in
                         login_response.text)

        if authenticated:
            log.info("Authentication successful!")
            self.USERNAME = username
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:my.nrao.edu", username, password)

        return authenticated
Beispiel #31
0
        ):

            for spw in (0, 1, 2, 3, 4, 5, 6, 7):
                filename = ftemplate.format(
                    spw=spw,
                    field=field,
                    band=band,
                    array=array,
                    suffix=suffix,
                    robust=robust,
                )

                if os.path.exists(filename):
                    cube = SpectralCube.read(filename, use_dask=True)
                else:
                    log.exception("File {0} does not exist".format(filename))
                    if os.path.exists(filename[:-5]):
                        log.exception("But {0} does!!!!".format(filename[:-5]))
                    continue

                for operation in ('mean', 'max', 'median'):
                    out_fn = f'spectra/{field}_{array}_{band}_spw{spw}_robust{robust}{suffix}.{operation}spec.fits'
                    if overwrite or not os.path.exists(out_fn):
                        spec = getattr(cube, operation)(axis=(1, 2))
                        #spec = cube.apply_numpy_function(getattr(np, 'nan'+operation),
                        #                                 axis=(1,2),
                        #                                 progressbar=True,
                        #                                 projection=True,
                        #                                 how='slice',
                        #                                 unit=cube.unit,
                        #                                )
Beispiel #32
0
def argparsing():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('-f',
                        '--file',
                        dest='input_paths',
                        default=[get_path('gamma_test.simtel.gz')],
                        nargs='*',
                        help='path to the input files to be combined for a '
                        'single charge resolution.')
    parser.add_argument('-O',
                        '--origin',
                        dest='origin',
                        action='store',
                        choices=InputFile.origin_list(),
                        default='hessio',
                        help='origin of the file')
    parser.add_argument('-t',
                        '--telescope',
                        dest='tel',
                        action='store',
                        type=int,
                        default=None,
                        nargs='*',
                        help='list of telecopes to be included. '
                        'Default = All')
    parser.add_argument('-o',
                        '--output',
                        dest='output_path',
                        action='store',
                        default=None,
                        help='path to store a pdf output of the plots. '
                        'default = display on screen instead')
    parser.add_argument('--comparison',
                        dest='comparison',
                        action='store',
                        default=None,
                        help='output path for a True Charge versus Measured'
                        'Charge graph. Default = do not plot graph')
    parser.add_argument('-M',
                        '--maxpe',
                        dest='maxpe',
                        action='store',
                        default=None,
                        type=float,
                        help='maximum pe to calculate the charge resolution'
                        ' up to. Default = maximum pe in file')
    parser.add_argument('--maxpeplot',
                        dest='maxpeplot',
                        action='store',
                        default=None,
                        type=float,
                        help='maximum pe to plot up to. Default = maxpe')
    parser.add_argument('-B',
                        '--binning',
                        dest='binning',
                        action='store',
                        default="log",
                        choices=['none', 'normal', 'log'],
                        help='binning of the charge resoltion graph: '
                        '"none" = no binning, "normal" = bin, '
                        '"log" = bin in log space.')
    parser.add_argument('--normalx',
                        dest='normalx',
                        action='store_true',
                        default=False,
                        help='Use a normal x axis instead of the defualt log'
                        'axis')
    parser.add_argument('--normaly',
                        dest='normaly',
                        action='store_true',
                        default=False,
                        help='Use a normal y axis instead of the defualt log'
                        'axis')
    parser.add_argument('-E',
                        '--example',
                        dest='example',
                        action='store_true',
                        default=False,
                        help='print an example runcard')
    parser.add_argument('-R',
                        '--runcard',
                        dest='runcard',
                        action='store',
                        default=None,
                        help='path to a runcard text file with arguments that '
                        'override command line arguments. This run card '
                        'can allow complex combinations of files and '
                        'calibrations to compare the charge resolution '
                        'against each other.')
    parser.add_argument('--chargeres-names',
                        dest='chargeres_names',
                        default=['default'],
                        nargs='*',
                        help='chargres calculation to include in plot. '
                        'Only used for runcards.')
    parser.add_argument('--calib-help',
                        dest='calib_help',
                        action='store_true',
                        default=False,
                        help='display the arguments used for the camera '
                        'calibration')

    logger_detail = parser.add_mutually_exclusive_group()
    logger_detail.add_argument('-q',
                               '--quiet',
                               dest='quiet',
                               action='store_true',
                               default=False,
                               help='Quiet mode')
    logger_detail.add_argument('-v',
                               '--verbose',
                               dest='verbose',
                               action='store_true',
                               default=False,
                               help='Verbose mode')
    logger_detail.add_argument('-d',
                               '--debug',
                               dest='debug',
                               action='store_true',
                               default=False,
                               help='Debug mode')

    args, excess_args = parser.parse_known_args()

    if args.quiet:
        log.setLevel(40)
    if args.verbose:
        log.setLevel(20)
    if args.debug:
        log.setLevel(10)

    if args.calib_help:
        params, unknown_args = calibration_parameters(excess_args, args.origin,
                                                      args.calib_help)

    if args.example:
        print("""
# Each charge resolution block starts with [chargeres] and the names for
# this charge resolution.
# The options in each block are equivalent to the scripts help message.
# Options that seem to apply to plotting will only have effect in a
# plotting block.

[chargeres] test_file_local
#-f gamma_test.simtel.gz
-f ~/Software/outputs/sim_telarray/simtel_run4_gcts_hnsb.gz
-O hessio
--integrator 4
--integration-window 7 3
--integration-sigamp 2 4
--integration-lwt 0
--integration-calib_scale 1.05
--comparison ~/Downloads/test_file_local.pdf


# A second charge resolution block to also calculate the resolution with
# a different integrator so the two resolutions can be plotted against
# each other.

[chargeres] test_file_nei
#-f gamma_test.simtel.gz
-f ~/Software/outputs/sim_telarray/simtel_run4_gcts_hnsb.gz
-O hessio
--integrator 5
--integration-window 7 3
--integration-sigamp 2 4
--integration-lwt 0
--integration-calib_scale 1.05
--comparison ~/Downloads/test_file_nei.pdf

# A plotting block configures an output plot

[plot] normal_plot
--chargeres-names test_file_local test_file_nei
-o ~/Downloads/normal_plot.pdf
--binning normal
--normalx
--normaly

[plot] log_plot
--chargeres-names test_file_local test_file_nei
-o ~/Downloads/log_plot.pdf""")
        exit()

    chargeres_cmdlines = {}
    plot_cmdlines = {}

    if args.runcard is None:
        name = args.chargeres_names[0]
        chargeres_cmdlines[name] = sys.argv[1:]
        plot_cmdlines[name] = sys.argv[1:]
        chargeres_args = {name: args}
        plot_args = {name: args}
    else:
        chargeres_args = {}
        plot_args = {}
        current = None
        runcard = open(args.runcard)
        for line in runcard:
            if line.strip() and not line.startswith('#'):
                argument = line.split()[0]
                if argument == '[chargeres]':
                    name = line.split()[1:][0]
                    chargeres_cmdlines[name] = []
                    current = chargeres_cmdlines[name]
                    continue
                elif argument == '[plot]':
                    name = line.split()[1:][0]
                    plot_cmdlines[name] = []
                    current = plot_cmdlines[name]
                    continue
                current.extend(line.split())

        # Temp fill for checks
        for name, cmdline in chargeres_cmdlines.items():
            chargeres_args[name], unknown = parser.parse_known_args(cmdline)
        for name, cmdline in plot_cmdlines.items():
            plot_args[name], unknown = parser.parse_known_args(cmdline)

    # Check all chargeres_names exist
    for plot_name, args in plot_args.items():
        for name in args.chargeres_names:
            try:
                if name not in chargeres_args:
                    raise IndexError
            except IndexError:
                log.exception("[chargeres_names] For plot: {}, no chargeres "
                              "has the name: {}".format(plot_name, name))
                raise

    return parser, chargeres_cmdlines, plot_cmdlines
Beispiel #33
0
def calibrate_event(event, params, geom_dict=None):
    """
    Generic calibrator for events. Calls the calibrator corresponding to the
    source of the event, and stores the dl1 (calibrated_image) information into a
    new event container.

    Parameters
    ----------
    event : container
        A `ctapipe` event container
    params : dict
        REQUIRED:

        params['integrator'] - Integration scheme

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_clip_amp'] - Amplitude in p.e. above which the
        signal is clipped.

        params['integration_calib_scale'] : Identical to global variable
        CALIB_SCALE in reconstruct.c in hessioxxx software package. 0.92 is
        the default value (corresponds to HESS). The required value changes
        between cameras (GCT = 1.05).

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).
    geom_dict : dict
        Dict of pixel geometry for each telescope. Leave as None for automatic
        calculation when it is required.
        dict[(num_pixels, focal_length)] = `ctapipe.io.CameraGeometry`

    Returns
    -------
    calibrated : container
        A new `ctapipe` event container containing the dl1 information, and a
        reference to all other information contained in the original event
        container.
    """

    # Obtain relevent calibrator
    switch = {
        'hessio':
            partial(mc.calibrate_mc, event=event, params=params)
        }
    try:
        calibrator = switch[event.meta['source']]
    except KeyError:
        log.exception("no calibration created for data origin: '{}'"
                      .format(event.meta['source']))
        raise

    # KPK: should not copy the event here! there is no reason to
    # Copying is
    # up to the user if they want to do it, not in the algorithms.
    #    calibrated = copy(event)

    # params stored in metadata
    event.dl1.meta.update(params)

    # Fill dl1
    event.dl1.reset()
    for telid in event.dl0.tels_with_data:
        nchan = event.inst.num_channels[telid]
        npix = event.inst.num_pixels[telid]
        event.dl1.tel[telid] = CalibratedCameraContainer()

        # Get geometry
        int_dict, inverted = integrator_dict()
        geom = None

        # Check if geom is even needed for integrator
        if inverted[params['integrator']] in integrators_requiring_geom():
            if geom_dict is not None and telid in geom_dict:
                geom = geom_dict[telid]
            else:
                log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                            event.inst.optical_foclen[telid])
                log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[telid] = geom

        pe, window, data_ped, peakpos = calibrator(telid=telid, geom=geom)
        tel = event.dl1.tel[telid]
        tel.calibrated_image = pe
        tel.peakpos = peakpos
        for chan in range(nchan):
            tel.integration_window[chan] = window[chan]
            tel.pedestal_subtracted_adc[chan] = data_ped[chan]

    return event
                                      parlimits=[(5,300), (11,17), (3,7), (0,0), (0,0)],
                                      parsteps=[0.01,0.01,0.1,0,0], fitunits='Hz',
                                      texgrid=((218.1,218.3,texgrid303),
                                               (218.35,218.55,texgrid322),
                                               (218.6,218.85,texgrid321)),
                                      # specify the frequency range over which the grid is valid (in GHz)
                                      taugrid=((218.1,218.3,taugrid303),
                                               (218.35,218.55,taugrid322),
                                               (218.6,218.85,taugrid321)),
                                      hdr=hdrb,
                                      shortvarnames=("T","N","n","v","\\sigma"),
                                      # specify the parameter names (TeX is OK)
                                      grid_vwidth=5.0,
                                      )
except IOError as ex:
    log.exception("Could not read files from disk: cannot load H2CO RADEX fitter")
    log.exception(ex)


def simplemodel(xarr, amplitude, velocity, width, ratio, amp2):

    x = xarr.as_unit('km/s')
    voff1 = x.x_to_coord(218.475632e9,'Hz')
    voff2 = x.x_to_coord(218.760066e9,'Hz')
    voff3 = x.x_to_coord(218.44005,'GHz')
    x = np.array(x) # make sure xarr is no longer a spectroscopic axis
    G = (amplitude*(np.exp(-(x-velocity)**2/(2.0*width**2)) +
                    ratio*np.exp(-(x-velocity-voff1)**2/(2.0*width**2)) +
                    ratio*np.exp(-(x-velocity-voff2)**2/(2.0*width**2))) +
         amp2 * np.exp(-(x-velocity-voff3)**2/(2.0*width**2)))
Beispiel #35
0
def nb_peak_integration(data, geom, params):
    """
    Integrate sample-mode data (traces) around a peak in the signal sum of
    neighbouring pixels.

    The integration window can be anywhere in the available length
    of the traces.

    No weighting of individual samples is applied.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    geom : `ctapipe.io.CameraGeometry`
        geometry of the camera's pixels
    params : dict
        REQUIRED:

        params['window'] - Integration window size

        params['shift'] - Starting sample for this integration

        (adapted such that window fits into readout).

        OPTIONAL:

        params['sigamp'] - Amplitude in ADC counts above pedestal at which a
        signal is considered as significant (separate for high gain/low gain).

        params['lwt']
        - Weight of the local pixel (0: peak from neighbours
        only, 1: local pixel counts as much as any neighbour).

    Returns
    -------
    integration : ndarray
        array of pixels with integrated charge [ADC counts]
        (pedestal substracted)
    integration_window : ndarray
        bool array of same shape as data. Specified which samples are included
        in the integration window
    peakpos : ndarray
        position of the peak as determined by the peak-finding algorithm
        for each pixel and channel
    """

    try:
        if 'window' not in params or 'shift' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    nchan, npix, nsamples = data.shape

    # Extract significant entries
    sig_entries = np.ones_like(data, dtype=bool)
    if 'sigamp' in params:
        sigamp_cut = params['sigamp']
        for i in range(len(sigamp_cut) if len(sigamp_cut) <= nchan else nchan):
            sig_entries[i] = data[i] > sigamp_cut[i]
    sig_pixels = np.any(sig_entries, axis=2)
    sig_channel = np.any(sig_pixels, axis=1)
    if not sig_channel[0] == True:
        log.error("[ERROR] sigamp value excludes all values in HG channel")
    significant_data = data * sig_entries

    # Define window
    lwt = 0 if 'lwt' not in params else params['lwt']
    neighbour_list = geom.neighbors
    peakpos = np.zeros_like(sig_pixels, dtype=np.int)
    for ipix, neighbours in enumerate(neighbour_list):
        nb_data = significant_data[:, neighbours]
        weighted_pixel = significant_data[:, ipix] * lwt
        """@type weighted_pixel: numpy.core.multiarray.ndarray"""
        pixel_expanded = np.expand_dims(weighted_pixel, axis=1)
        all_data = np.concatenate((nb_data, pixel_expanded), axis=1)
        sum_data = all_data.sum(1)
        peakpos[:, ipix] = sum_data.argmax(1)
    start = (peakpos - params['shift'])
    window = params['window']

    # Check window is within readout
    if window > nsamples:
        window = nsamples
    start[np.where(start < 0)] = 0
    start[np.where(start + window > nsamples)] = nsamples - window

    # Select entries
    integration_window = np.zeros_like(data, dtype=bool)
    for i in range(nchan):
        for j in range(npix):
            integration_window[i, j, start[i, j]:start[i, j] + window] = True
    windowed_data = data * integration_window

    # Integrate
    integration = np.round(windowed_data.sum(2)).astype(np.int)

    return integration, integration_window, peakpos
Beispiel #36
0
def nb_peak_integration(data, geom, params):
    """
    Integrate sample-mode data (traces) around a peak in the signal sum of
    neighbouring pixels.

    The integration window can be anywhere in the available length
    of the traces.

    No weighting of individual samples is applied.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    geom : `ctapipe.io.CameraGeometry`
        geometry of the camera's pixels
    params : dict
        REQUIRED:

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).

        params['integration_lwt']
        - Weight of the local pixel (0: peak from neighbours
        only, 1: local pixel counts as much as any neighbour).

    Returns
    -------
    integration : ndarray
        array of pixels with integrated charge [ADC counts]
        (pedestal substracted)
    integration_window : ndarray
        bool array of same shape as data. Specified which samples are included
        in the integration window
    peakpos : ndarray
        position of the peak as determined by the peak-finding algorithm
        for each pixel and channel
    """

    try:
        if 'integration_window' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    nchan, npix, nsamples = data.shape

    # Extract significant entries
    sig_entries = np.ones_like(data, dtype=bool)
    if 'integration_sigamp' in params:
        sigamp_cut = params['integration_sigamp']
        for i in range(len(sigamp_cut) if len(sigamp_cut) <= nchan else nchan):
            sig_entries[i] = data[i] > sigamp_cut[i]
    sig_pixels = np.any(sig_entries, axis=2)
    sig_channel = np.any(sig_pixels, axis=1)
    if not sig_channel[0] == True:
        log.error("[ERROR] sigamp value excludes all values in HG channel")
    significant_data = data * sig_entries

    # Define window
    lwt = 0 if 'integration_lwt' not in params else params['integration_lwt']
    neighbour_list = geom.neighbors
    peakpos = np.zeros_like(sig_pixels, dtype=np.int)
    for ipix, neighbours in enumerate(neighbour_list):
        nb_data = significant_data[:, neighbours]
        weighted_pixel = significant_data[:, ipix] * lwt
        """@type weighted_pixel: numpy.core.multiarray.ndarray"""
        pixel_expanded = np.expand_dims(weighted_pixel, axis=1)
        all_data = np.concatenate((nb_data, pixel_expanded), axis=1)
        sum_data = all_data.sum(1)
        peakpos[:, ipix] = sum_data.argmax(1)
    window = params['integration_window'][0]
    shift = params['integration_window'][1]
    start = (peakpos - shift)

    # Check window is within readout
    if window > nsamples:
        window = nsamples
    start[np.where(start < 0)] = 0
    start[np.where(start + window > nsamples)] = nsamples - window

    # Select entries
    integration_window = np.zeros_like(data, dtype=bool)
    for i in range(nchan):
        for j in range(npix):
            integration_window[i, j, start[i, j]:start[i, j] + window] = True
    windowed_data = data * integration_window

    # Integrate
    integration = np.round(windowed_data.sum(2)).astype(np.int)

    return integration, integration_window, peakpos
Beispiel #37
0
def simple_integration(data, params):
    """
    Integrate sample-mode data (traces) over a common and fixed interval.

    The integration window can be anywhere in the available length of
    the traces.

    No weighting of individual samples is applied.

    Note: for multiple gains, this results in identical integration regions.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    params : dict
        REQUIRED:

        params['integration_window'] - Integration window size and starting
        sample for this integration

        (adapted such that window fits into readout).

    Returns
    -------
    integration : ndarray
        array of pixels with integrated charge [ADC counts]
        (pedestal substracted)
    integration_window : ndarray
        bool array of same shape as data. Specified which samples are included
        in the integration window
    peakpos : ndarray
        position of the peak as determined by the peak-finding algorithm
        for each pixel and channel
    """

    try:
        if 'integration_window' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")

    nchan, npix, nsamples = data.shape

    # Define window
    window = params['integration_window'][0]
    start = params['integration_window'][1]

    # Check window is within readout
    if window > nsamples:
        window = nsamples
    if start < 0:
        start = 0
    if start + window > nsamples:
        start = nsamples - window

    # Select entries
    integration_window = np.zeros_like(data, dtype=bool)
    integration_window[:, :, start:start + window] = True
    windowed_data = data * integration_window

    # Integrate
    integration = np.round(windowed_data.sum(2)).astype(np.int)

    return integration, integration_window, [None, None]
Beispiel #38
0
def local_peak_integration(data, params):
    """
    Integrate sample-mode data (traces) around a pixel-local signal peak.

    The integration window can be anywhere in the available
    length of the traces.

    No weighting of individual samples is applied.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    params : dict
        REQUIRED:

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).

    Returns
    -------
    integration : ndarray
        array of pixels with integrated charge [ADC counts]
        (pedestal substracted)
    integration_window : ndarray
        bool array of same shape as data. Specified which samples are included
        in the integration window
    peakpos : ndarray
        position of the peak as determined by the peak-finding algorithm
        for each pixel and channel
    """

    try:
        if 'integration_window' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    nchan, npix, nsamples = data.shape

    # Extract significant entries
    sig_entries = np.ones_like(data, dtype=bool)
    if 'integration_sigamp' in params:
        sigamp_cut = params['integration_sigamp']
        for i in range(len(sigamp_cut) if len(sigamp_cut) <= nchan else nchan):
            sig_entries[i] = data[i] > sigamp_cut[i]
    sig_pixels = np.any(sig_entries, axis=2)
    sig_channel = np.any(sig_pixels, axis=1)
    if not sig_channel[0] == True:
        log.error("[ERROR] sigamp value excludes all values in HG channel")
    significant_data = data * sig_entries

    # Define window
    peakpos = significant_data.argmax(2)
    if nchan > 1:  # If the LG is not significant, takes the HG peakpos
        peakpos[1] = np.where(sig_pixels[1] < sig_pixels[0], peakpos[0],
                              peakpos[1])
    window = params['integration_window'][0]
    shift = params['integration_window'][1]
    start = (peakpos - shift)

    # Check window is within readout
    if window > nsamples:
        window = nsamples
    start[np.where(start < 0)] = 0
    start[np.where(start + window > nsamples)] = nsamples - window

    # Select entries
    integration_window = np.zeros_like(data, dtype=bool)
    for i in range(nchan):
        for j in range(npix):
            integration_window[i, j, start[i, j]:start[i, j] + window] = True
    windowed_data = data * integration_window

    # Integrate
    integration = np.round(windowed_data.sum(2)).astype(np.int)

    return integration, integration_window, peakpos
Beispiel #39
0
    def _login(self, username=None, store_password=False,
               reenter_password=False):
        """
        Login to the ALMA Science Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ALMA Science Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """

        if username is None:
            if not self.USERNAME:
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # set session cookies (they do not get set otherwise)
        cookiesetpage = self._request("GET",
                                      urljoin(self._get_dataarchive_url(),
                                              'rh/forceAuthentication'),
                                      cache=False)
        self._login_cookiepage = cookiesetpage
        cookiesetpage.raise_for_status()
        assert 'rh-cas.alma.cl/cas/login' in cookiesetpage.request.url

        # Check if already logged in
        loginpage = self._request("GET", "https://rh-cas.alma.cl/cas/login",
                                  cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        # Get password from keyring or prompt
        password, password_from_keyring = self._get_password(
            "astroquery:rh-cas.alma.cl", username, reenter=reenter_password)

        # Authenticate
        log.info("Authenticating {0} on rh-cas.alma.cl ...".format(username))
        # Do not cache pieces of the login process
        data = {kw: root.find('input', {'name': kw})['value']
                for kw in ('lt', '_eventId', 'execution')}
        data['username'] = username
        data['password'] = password
        data['submit'] = 'LOGIN'

        login_response = self._request("POST", "https://rh-cas.alma.cl/cas/login",
                                       params={'service': self._get_dataarchive_url()},
                                       data=data,
                                       cache=False)

        # save the login response for debugging purposes
        self._login_response = login_response
        # do not expose password back to user
        del data['password']
        # but save the parameters for debug purposes
        self._login_parameters = data

        authenticated = ('You have successfully logged in' in
                         login_response.text)

        if authenticated:
            log.info("Authentication successful!")
            self.USERNAME = username
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:rh-cas.alma.cl", username, password)
        return authenticated
    # # this deserves a lot of explanation:
    # # models.formaldehyde.formaldehyde_radex is the MODEL that we are going to fit
    # # models.model.SpectralModel is a wrapper to deal with parinfo, multiple peaks,
    # # and annotations
    # # all of the parameters after the first are passed to the model function

    h2co_radex_fitter = SpectralModel(
        models.formaldehyde_mm.formaldehyde_mm_radex,
        5,
        parnames=['temperature', 'column', 'density', 'center', 'width'],
        parvalues=[50, 12, 4.5, 0, 1],
        parlimited=[(True, True), (True, True), (True, True), (False, False),
                    (True, False)],
        parlimits=[(5, 300), (11, 17), (3, 7), (0, 0), (0, 0)],
        parsteps=[0.01, 0.01, 0.1, 0, 0],
        fitunits='Hz',
        texgrid=((218.1, 218.3, texgrid303), (218.35, 218.55, texgrid322),
                 (218.6, 218.85, texgrid321)),
        # specify the frequency range over which the grid is valid (in GHz)
        taugrid=((218.1, 218.3, taugrid303), (218.35, 218.55, taugrid322),
                 (218.6, 218.85, taugrid321)),
        hdr=hdrb,
        shortvarnames=("T", "N", "n", "v", "\\sigma"),
        # specify the parameter names (TeX is OK)
        grid_vwidth=5.0,
    )
except IOError as ex:
    log.exception(
        "Could not read files from disk: cannot load H2CO RADEX fitter")
    log.exception(ex)
Beispiel #41
0
    def _login(self,
               username=None,
               store_password=False,
               reenter_password=False):
        """
        Login to the ALMA Science Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ALMA Science Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """

        if username is None:
            if self.USERNAME == "":
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Check if already logged in
        loginpage = self._request("GET",
                                  "https://asa.alma.cl/cas/login",
                                  cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        # Get password from keyring or prompt
        if reenter_password is False:
            password_from_keyring = keyring.get_password(
                "astroquery:asa.alma.cl", username)
        else:
            password_from_keyring = None

        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warn("You may be using an ipython notebook:"
                         " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your ALMA password:"******"\n".format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on asa.alma.cl ...".format(username))
        # Do not cache pieces of the login process
        data = {
            kw: root.find('input', {'name': kw})['value']
            for kw in ('lt', '_eventId', 'execution')
        }
        data['username'] = username
        data['password'] = password

        login_response = self._request(
            "POST",
            "https://asa.alma.cl/cas/login",
            params={'service': urljoin(self.archive_url, 'rh/login')},
            data=data,
            cache=False)

        authenticated = ('You have successfully logged in'
                         in login_response.text)

        if authenticated:
            log.info("Authentication successful!")
            self._username = username
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:asa.alma.cl", username, password)
        return authenticated
Beispiel #42
0
def set_integration_correction(event, telid, params):
    """
    Obtain the integration correction for the window specified

        Parameters
    ----------
    event : container
        A `ctapipe` event container
    telid : int
        telescope id
    params : dict
        REQUIRED:

        params['window'] - Integration window size

        params['shift'] - Starting sample for this integration

        (adapted such that window fits into readout).

    Returns
    -------
    correction : float
        Value of the integration correction for this instrument \n
    """

    try:
        if 'window' not in params or 'shift' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    nchan = event.dl0.tel[telid].num_channels
    nsamples = event.dl0.tel[telid].num_samples

    # Reference pulse parameters
    refshapes = np.array(list(event.mc.tel[telid].refshapes.values()))
    refstep = event.mc.tel[telid].refstep
    nrefstep = event.mc.tel[telid].lrefshape
    x = np.arange(0, refstep*nrefstep, refstep)
    y = refshapes[nchan-1]
    refipeak = np.argmax(y)

    # Sampling pulse parameters
    time_slice = event.mc.tel[telid].time_slice
    x1 = np.arange(0, refstep*nrefstep, time_slice)
    y1 = interp(x1, x, y)
    ipeak = np.argmin(np.abs(x1-x[refipeak]))

    # Check window is within readout
    start = ipeak - params['shift']
    window = params['window']
    if window > nsamples:
        window = nsamples
    if start < 0:
        start = 0
    if start + window > nsamples:
        start = nsamples - window

    correction = round((sum(y) * refstep) / (sum(y1[start:start + window]) *
                                             time_slice), 7)

    return correction
Beispiel #43
0
def local_peak_integration(data, params):
    """
    Integrate sample-mode data (traces) around a pixel-local signal peak.

    The integration window can be anywhere in the available
    length of the traces.

    No weighting of individual samples is applied.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    params : dict
        REQUIRED:

        params['window'] - Integration window size

        params['shift'] - Starting sample for this integration

        (adapted such that window fits into readout).

        OPTIONAL:

        params['sigamp'] - Amplitude in ADC counts above pedestal at which a
        signal is considered as significant (separate for high gain/low gain).

    Returns
    -------
    integration : ndarray
        array of pixels with integrated charge [ADC counts]
        (pedestal substracted)
    integration_window : ndarray
        bool array of same shape as data. Specified which samples are included
        in the integration window
    peakpos : ndarray
        position of the peak as determined by the peak-finding algorithm
        for each pixel and channel
    """

    try:
        if 'window' not in params or 'shift' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    nchan, npix, nsamples = data.shape

    # Extract significant entries
    sig_entries = np.ones_like(data, dtype=bool)
    if 'sigamp' in params:
        sigamp_cut = params['sigamp']
        for i in range(len(sigamp_cut) if len(sigamp_cut) <= nchan else nchan):
            sig_entries[i] = data[i] > sigamp_cut[i]
    sig_pixels = np.any(sig_entries, axis=2)
    sig_channel = np.any(sig_pixels, axis=1)
    if not sig_channel[0] == True:
        log.error("[ERROR] sigamp value excludes all values in HG channel")
    significant_data = data * sig_entries

    # Define window
    peakpos = significant_data.argmax(2)
    if nchan > 1:  # If the LG is not significant, takes the HG peakpos
        peakpos[1] = np.where(sig_pixels[1] < sig_pixels[0], peakpos[0],
                              peakpos[1])
    start = (peakpos - params['shift'])
    window = params['window']

    # Check window is within readout
    if window > nsamples:
        window = nsamples
    start[np.where(start < 0)] = 0
    start[np.where(start + window > nsamples)] = nsamples - window

    # Select entries
    integration_window = np.zeros_like(data, dtype=bool)
    for i in range(nchan):
        for j in range(npix):
            integration_window[i, j, start[i, j]:start[i, j] + window] = True
    windowed_data = data * integration_window

    # Integrate
    integration = np.round(windowed_data.sum(2)).astype(np.int)

    return integration, integration_window, peakpos
Beispiel #44
0
def set_integration_correction(event, telid, params):
    """
    Obtain the integration correction for the window specified

    Parameters
    ----------
    event : container
        A `ctapipe` event container
    telid : int
        telescope id
    params : dict
        REQUIRED:

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

    Returns
    -------
    correction : float
        Value of the integration correction for this instrument \n
    """

    try:
        if 'integration_window' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    nchan = event.dl0.tel[telid].num_channels
    nsamples = event.dl0.tel[telid].num_samples

    # Reference pulse parameters
    refshapes = np.array(list(event.mc.tel[telid].refshapes.values()))
    refstep = event.mc.tel[telid].refstep
    nrefstep = event.mc.tel[telid].lrefshape
    x = np.arange(0, refstep*nrefstep, refstep)
    y = refshapes[nchan-1]
    refipeak = np.argmax(y)

    # Sampling pulse parameters
    time_slice = event.mc.tel[telid].time_slice
    x1 = np.arange(0, refstep*nrefstep, time_slice)
    y1 = interp(x1, x, y)
    ipeak = np.argmin(np.abs(x1-x[refipeak]))

    # Check window is within readout
    window = params['integration_window'][0]
    shift = params['integration_window'][1]
    start = ipeak - shift
    if window > nsamples:
        window = nsamples
    if start < 0:
        start = 0
    if start + window > nsamples:
        start = nsamples - window

    correction = round((sum(y) * refstep) / (sum(y1[start:start + window]) *
                                             time_slice), 7)

    return correction
def argparsing():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('-f', '--file', dest='input_paths',
                        default=[get_path('gamma_test.simtel.gz')], nargs='*',
                        help='path to the input files to be combined for a '
                             'single charge resolution.')
    parser.add_argument('-O', '--origin', dest='origin', action='store',
                        choices=InputFile.origin_list(),
                        default='hessio', help='origin of the file')
    parser.add_argument('-t', '--telescope', dest='tel', action='store',
                        type=int, default=None, nargs='*',
                        help='list of telecopes to be included. '
                             'Default = All')
    parser.add_argument('-o', '--output', dest='output_path', action='store',
                        default=None,
                        help='path to store a pdf output of the plots. '
                             'default = display on screen instead')
    parser.add_argument('--comparison', dest='comparison', action='store',
                        default=None,
                        help='output path for a True Charge versus Measured'
                             'Charge graph. Default = do not plot graph')
    parser.add_argument('-M', '--maxpe', dest='maxpe', action='store',
                        default=None, type=float,
                        help='maximum pe to calculate the charge resolution'
                             ' up to. Default = maximum pe in file')
    parser.add_argument('--maxpeplot', dest='maxpeplot', action='store',
                        default=None, type=float,
                        help='maximum pe to plot up to. Default = maxpe')
    parser.add_argument('-B', '--binning', dest='binning', action='store',
                        default="log", choices=['none', 'normal', 'log'],
                        help='binning of the charge resoltion graph: '
                             '"none" = no binning, "normal" = bin, '
                             '"log" = bin in log space.')
    parser.add_argument('--normalx', dest='normalx', action='store_true',
                        default=False,
                        help='Use a normal x axis instead of the defualt log'
                             'axis')
    parser.add_argument('--normaly', dest='normaly', action='store_true',
                        default=False,
                        help='Use a normal y axis instead of the defualt log'
                             'axis')
    parser.add_argument('-E', '--example', dest='example', action='store_true',
                        default=False,
                        help='print an example runcard')
    parser.add_argument('-R', '--runcard', dest='runcard', action='store',
                        default=None,
                        help='path to a runcard text file with arguments that '
                             'override command line arguments. This run card '
                             'can allow complex combinations of files and '
                             'calibrations to compare the charge resolution '
                             'against each other.')
    parser.add_argument('--chargeres-names', dest='chargeres_names',
                        default=['default'], nargs='*',
                        help='chargres calculation to include in plot. '
                             'Only used for runcards.')
    parser.add_argument('--calib-help', dest='calib_help', action='store_true',
                        default=False,
                        help='display the arguments used for the camera '
                             'calibration')

    logger_detail = parser.add_mutually_exclusive_group()
    logger_detail.add_argument('-q', '--quiet', dest='quiet',
                               action='store_true', default=False,
                               help='Quiet mode')
    logger_detail.add_argument('-v', '--verbose', dest='verbose',
                               action='store_true', default=False,
                               help='Verbose mode')
    logger_detail.add_argument('-d', '--debug', dest='debug',
                               action='store_true', default=False,
                               help='Debug mode')

    args, excess_args = parser.parse_known_args()

    if args.quiet:
        log.setLevel(40)
    if args.verbose:
        log.setLevel(20)
    if args.debug:
        log.setLevel(10)

    if args.calib_help:
        params, unknown_args = calibration_parameters(excess_args,
                                                      args.origin,
                                                      args.calib_help)

    if args.example:
        print("""
# Each charge resolution block starts with [chargeres] and the names for
# this charge resolution.
# The options in each block are equivalent to the scripts help message.
# Options that seem to apply to plotting will only have effect in a
# plotting block.

[chargeres] test_file_local
#-f gamma_test.simtel.gz
-f ~/Software/outputs/sim_telarray/simtel_run4_gcts_hnsb.gz
-O hessio
--integrator 4
--integration-window 7 3
--integration-sigamp 2 4
--integration-lwt 0
--integration-calib_scale 1.05
--comparison ~/Downloads/test_file_local.pdf


# A second charge resolution block to also calculate the resolution with
# a different integrator so the two resolutions can be plotted against
# each other.

[chargeres] test_file_nei
#-f gamma_test.simtel.gz
-f ~/Software/outputs/sim_telarray/simtel_run4_gcts_hnsb.gz
-O hessio
--integrator 5
--integration-window 7 3
--integration-sigamp 2 4
--integration-lwt 0
--integration-calib_scale 1.05
--comparison ~/Downloads/test_file_nei.pdf

# A plotting block configures an output plot

[plot] normal_plot
--chargeres-names test_file_local test_file_nei
-o ~/Downloads/normal_plot.pdf
--binning normal
--normalx
--normaly

[plot] log_plot
--chargeres-names test_file_local test_file_nei
-o ~/Downloads/log_plot.pdf""")
        exit()

    chargeres_cmdlines = {}
    plot_cmdlines = {}

    if args.runcard is None:
        name = args.chargeres_names[0]
        chargeres_cmdlines[name] = sys.argv[1:]
        plot_cmdlines[name] = sys.argv[1:]
        chargeres_args = {name: args}
        plot_args = {name: args}
    else:
        chargeres_args = {}
        plot_args = {}
        current = None
        runcard = open(args.runcard)
        for line in runcard:
            if line.strip() and not line.startswith('#'):
                argument = line.split()[0]
                if argument == '[chargeres]':
                    name = line.split()[1:][0]
                    chargeres_cmdlines[name] = []
                    current = chargeres_cmdlines[name]
                    continue
                elif argument == '[plot]':
                    name = line.split()[1:][0]
                    plot_cmdlines[name] = []
                    current = plot_cmdlines[name]
                    continue
                current.extend(line.split())

        # Temp fill for checks
        for name, cmdline in chargeres_cmdlines.items():
            chargeres_args[name], unknown = parser.parse_known_args(cmdline)
        for name, cmdline in plot_cmdlines.items():
            plot_args[name], unknown = parser.parse_known_args(cmdline)

    # Check all chargeres_names exist
    for plot_name, args in plot_args.items():
        for name in args.chargeres_names:
            try:
                if name not in chargeres_args:
                    raise IndexError
            except IndexError:
                log.exception("[chargeres_names] For plot: {}, no chargeres "
                              "has the name: {}".format(plot_name, name))
                raise 

    return parser, chargeres_cmdlines, plot_cmdlines
Beispiel #46
0
def global_peak_integration(data, params):
    """
    Integrate sample-mode data (traces) over a common interval around a
    global signal peak, found by a weighted average of the maximum in each
    pixel.

    The integration window can be anywhere in the available length of the
    traces.

    No weighting of individual samples is applied.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    params : dict
        REQUIRED:

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).

    Returns
    -------
    integration : ndarray
        array of pixels with integrated charge [ADC counts]
        (pedestal substracted)
    integration_window : ndarray
        bool array of same shape as data. Specified which samples are included
        in the integration window
    peakpos : ndarray
        position of the peak as determined by the peak-finding algorithm
        for each pixel and channel
    """

    try:
        if 'integration_window' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")

    nchan, npix, nsamples = data.shape

    # Extract significant entries
    sig_entries = np.ones_like(data, dtype=bool)
    if 'integration_sigamp' in params:
        sigamp_cut = params['integration_sigamp']
        for i in range(len(sigamp_cut) if len(sigamp_cut) <= nchan else nchan):
            sig_entries[i] = data[i] > sigamp_cut[i]
    sig_pixels = np.any(sig_entries, axis=2)
    sig_channel = np.any(sig_pixels, axis=1)
    if not sig_channel[0] == True:
        log.error("[ERROR] sigamp value excludes all values in HG channel")
    significant_data = data * sig_entries

    # Define window
    max_time = significant_data.argmax(2)
    max_sample = significant_data.max(2)
    peakpos = np.zeros_like(max_sample, dtype=np.int)
    peakpos[0, :] = np.round(np.average(max_time[0], weights=max_sample[0]))
    if nchan > 1:
        if sig_channel[1]:
            peakpos[1, :] = np.round(
                np.average(max_time[1], weights=max_sample[1]))
        else:
            log.info("[calib] LG not significant, using HG for peak finding "
                     "instead")
            peakpos[1, :] = peakpos[0]
    window = params['integration_window'][0]
    shift = params['integration_window'][1]
    start = (peakpos - shift).astype(np.int)

    # Check window is within readout
    if window > nsamples:
        window = nsamples
    start[np.where(start < 0)] = 0
    start[np.where(start + window > nsamples)] = nsamples - window

    # Select entries
    integration_window = np.zeros_like(data, dtype=bool)
    for i in range(nchan):
        integration_window[i, :, start[i][0]:start[i][0] + window] = True
    windowed_data = data * integration_window

    # Integrate
    integration = np.round(windowed_data.sum(2)).astype(np.int)

    return integration, integration_window, peakpos
Beispiel #47
0
def calibrate_event(event, params, geom_dict=None):
    """
    Generic calibrator for events. Calls the calibrator corresponding to the
    source of the event, and stores the dl1 (pe_charge) information into a
    new event container.

    Parameters
    ----------
    event : container
        A `ctapipe` event container
    params : dict
        REQUIRED:

        params['integrator'] - Integration scheme

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_clip_amp'] - Amplitude in p.e. above which the
        signal is clipped.

        params['integration_calib_scale'] : Identical to global variable
        CALIB_SCALE in reconstruct.c in hessioxxx software package. 0.92 is
        the default value (corresponds to HESS). The required value changes
        between cameras (GCT = 1.05).

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).
    geom_dict : dict
        Dict of pixel geometry for each telescope. Leave as None for automatic
        calculation when it is required.
        dict[(num_pixels, focal_length)] = `ctapipe.io.CameraGeometry`

    Returns
    -------
    calibrated : container
        A new `ctapipe` event container containing the dl1 information, and a
        reference to all other information contained in the original event
        container.
    """

    # Obtain relevent calibrator
    switch = {'hessio': partial(mc.calibrate_mc, event=event, params=params)}
    try:
        calibrator = switch[event.meta.source]
    except KeyError:
        log.exception("no calibration created for data origin: '{}'".format(
            event.meta.source))
        raise

    calibrated = copy(event)

    # Add dl1 to the event container (if it hasn't already been added)
    try:
        calibrated.add_item("dl1", RawData())
        calibrated.dl1.run_id = event.dl0.run_id
        calibrated.dl1.event_id = event.dl0.event_id
        calibrated.dl1.tels_with_data = event.dl0.tels_with_data
        calibrated.dl1.calibration_parameters = params
    except AttributeError:
        pass

    # Fill dl1
    calibrated.dl1.tel = dict()  # clear the previous telescopes
    for telid in event.dl0.tels_with_data:
        nchan = event.dl0.tel[telid].num_channels
        npix = event.dl0.tel[telid].num_pixels
        calibrated.dl1.tel[telid] = CalibratedCameraData(telid)
        calibrated.dl1.tel[telid].num_channels = nchan
        calibrated.dl1.tel[telid].num_pixels = npix

        # Get geometry
        int_dict, inverted = integrator_dict()
        geom = None
        cam_dimensions = (event.dl0.tel[telid].num_pixels,
                          event.meta.optical_foclen[telid])
        # Check if geom is even needed for integrator
        if inverted[params['integrator']] in integrators_requiring_geom():
            if geom_dict is not None and telid in geom_dict:
                geom = geom_dict[telid]
            else:
                log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.meta.pixel_pos[telid],
                                            event.meta.optical_foclen[telid])
                log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[telid] = geom

        pe, window, data_ped, peakpos = calibrator(telid=telid, geom=geom)
        calibrated.dl1.tel[telid].pe_charge = pe
        calibrated.dl1.tel[telid].peakpos = peakpos
        for chan in range(nchan):
            calibrated.dl1.tel[telid].integration_window[chan] = window[chan]
            calibrated.dl1.tel[telid].pedestal_subtracted_adc[chan] = \
                data_ped[chan]

    return calibrated
Beispiel #48
0
    def _login(self,
               username=None,
               store_password=False,
               reenter_password=False):
        """
        Login to the ESO User Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ESO Public Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """
        if username is None:
            if self.USERNAME == "":
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Get password from keyring or prompt
        password_from_keyring = None
        if reenter_password is False:
            try:
                password_from_keyring = keyring.get_password(
                    "astroquery:www.eso.org", username)
            except keyring.errors.KeyringError as exc:
                log.warning("Failed to get a valid keyring for password "
                            "storage: {}".format(exc))

        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warning("You may be using an ipython notebook:"
                            " the password form will appear in your terminal.")
            password = getpass.getpass(
                "{0}, enter your ESO password:\n".format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on www.eso.org...".format(username))

        # Do not cache pieces of the login process
        login_response = self._request("GET",
                                       "https://www.eso.org/sso/login",
                                       cache=False)
        root = BeautifulSoup(login_response.content, 'html5lib')
        login_input = root.find(name='input', attrs={'name': 'execution'})
        if login_input is None:
            raise ValueError(
                "ESO login page did not have the correct attributes.")
        execution = login_input.get('value')

        login_result_response = self._request("POST",
                                              "https://www.eso.org/sso/login",
                                              data={
                                                  'username': username,
                                                  'password': password,
                                                  'execution': execution,
                                                  '_eventId': 'submit',
                                                  'geolocation': '',
                                              })
        login_result_response.raise_for_status()
        root = BeautifulSoup(login_result_response.content, 'html5lib')
        authenticated = root.find('h4').text == 'Login successful'

        if authenticated:
            log.info("Authentication successful!")
        else:
            log.exception("Authentication failed!")

        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:www.eso.org", username, password)
        return authenticated
Beispiel #49
0
def global_peak_integration(data, params):
    """
    Integrate sample-mode data (traces) over a common interval around a
    global signal peak, found by a weighted average of the maximum in each
    pixel.

    The integration window can be anywhere in the available length of the
    traces.

    No weighting of individual samples is applied.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    params : dict
        REQUIRED:

        params['window'] - Integration window size

        params['shift'] - Starting sample for this integration

        (adapted such that window fits into readout).

        OPTIONAL:

        params['sigamp'] - Amplitude in ADC counts above pedestal at which a
        signal is considered as significant (separate for high gain/low gain).

    Returns
    -------
    integration : ndarray
        array of pixels with integrated charge [ADC counts]
        (pedestal substracted)
    integration_window : ndarray
        bool array of same shape as data. Specified which samples are included
        in the integration window
    peakpos : ndarray
        position of the peak as determined by the peak-finding algorithm
        for each pixel and channel
    """

    try:
        if 'window' not in params or 'shift' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")

    nchan, npix, nsamples = data.shape

    # Extract significant entries
    sig_entries = np.ones_like(data, dtype=bool)
    if 'sigamp' in params:
        sigamp_cut = params['sigamp']
        for i in range(len(sigamp_cut) if len(sigamp_cut) <= nchan else nchan):
            sig_entries[i] = data[i] > sigamp_cut[i]
    sig_pixels = np.any(sig_entries, axis=2)
    sig_channel = np.any(sig_pixels, axis=1)
    if not sig_channel[0] == True:
        log.error("[ERROR] sigamp value excludes all values in HG channel")
    significant_data = data * sig_entries

    # Define window
    max_time = significant_data.argmax(2)
    max_sample = significant_data.max(2)
    peakpos = np.zeros_like(max_sample, dtype=np.int)
    peakpos[0, :] = np.round(np.average(max_time[0], weights=max_sample[0]))
    if nchan > 1:
        if sig_channel[1]:
            peakpos[1, :] = np.round(
                np.average(max_time[1], weights=max_sample[1]))
        else:
            log.info("[calib] LG not significant, using HG for peak finding "
                     "instead")
            peakpos[1, :] = peakpos[0]
    start = (peakpos - params['shift']).astype(np.int)
    window = params['window']

    # Check window is within readout
    if window > nsamples:
        window = nsamples
    start[np.where(start < 0)] = 0
    start[np.where(start + window > nsamples)] = nsamples - window

    # Select entries
    integration_window = np.zeros_like(data, dtype=bool)
    for i in range(nchan):
        integration_window[i, :, start[i][0]:start[i][0] + window] = True
    windowed_data = data * integration_window

    # Integrate
    integration = np.round(windowed_data.sum(2)).astype(np.int)

    return integration, integration_window, peakpos
Beispiel #50
0
def calibrate_event(event, params, geom_dict=None):
    """
    Generic calibrator for events. Calls the calibrator corresponding to the
    source of the event, and stores the dl1 (calibrated_image) information into a
    new event container.

    Parameters
    ----------
    event : container
        A `ctapipe` event container
    params : dict
        REQUIRED:

        params['integrator'] - Integration scheme

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_clip_amp'] - Amplitude in p.e. above which the
        signal is clipped.

        params['integration_calib_scale'] : Identical to global variable
        CALIB_SCALE in reconstruct.c in hessioxxx software package. 0.92 is
        the default value (corresponds to HESS). The required value changes
        between cameras (GCT = 1.05).

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).
    geom_dict : dict
        Dict of pixel geometry for each telescope. Leave as None for automatic
        calculation when it is required.
        dict[(num_pixels, focal_length)] = `ctapipe.io.CameraGeometry`

    Returns
    -------
    calibrated : container
        A new `ctapipe` event container containing the dl1 information, and a
        reference to all other information contained in the original event
        container.
    """

    # Obtain relevent calibrator
    switch = {'hessio': partial(mc.calibrate_mc, event=event, params=params)}
    try:
        calibrator = switch[event.meta['source']]
    except KeyError:
        log.exception("no calibration created for data origin: '{}'".format(
            event.meta['source']))
        raise

    # KPK: should not copy the event here! there is no reason to
    # Copying is
    # up to the user if they want to do it, not in the algorithms.
    #    calibrated = copy(event)

    # params stored in metadata
    event.dl1.meta.update(params)

    # Fill dl1
    event.dl1.reset()
    for telid in event.dl0.tels_with_data:
        nchan = event.inst.num_channels[telid]
        npix = event.inst.num_pixels[telid]
        event.dl1.tel[telid] = CalibratedCameraContainer()

        # Get geometry
        int_dict, inverted = integrator_dict()
        geom = None

        # Check if geom is even needed for integrator
        if inverted[params['integrator']] in integrators_requiring_geom():
            if geom_dict is not None and telid in geom_dict:
                geom = geom_dict[telid]
            else:
                log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                            event.inst.optical_foclen[telid])
                log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[telid] = geom

        pe, window, data_ped, peakpos = calibrator(telid=telid, geom=geom)
        tel = event.dl1.tel[telid]
        tel.calibrated_image = pe
        tel.peakpos = peakpos
        for chan in range(nchan):
            tel.integration_window[chan] = window[chan]
            tel.pedestal_subtracted_adc[chan] = data_ped[chan]

    return event
Beispiel #51
0
def simple_integration(data, params):
    """
    Integrate sample-mode data (traces) over a common and fixed interval.

    The integration window can be anywhere in the available length of
    the traces.

    No weighting of individual samples is applied.

    Note: for multiple gains, this results in identical integration regions.

    Parameters
    ----------
    data : ndarray
        3 dimensional numpy array containing the pedestal subtracted adc
        counts. data[nchan][npix][nsamples]
    params : dict
        REQUIRED:

        params['window'] - Integration window size

        params['shift'] - Starting sample for this integration

        (adapted such that window fits into readout).

    Returns
    -------
    integration : ndarray
        array of pixels with integrated charge [ADC counts]
        (pedestal substracted)
    integration_window : ndarray
        bool array of same shape as data. Specified which samples are included
        in the integration window
    peakpos : ndarray
        position of the peak as determined by the peak-finding algorithm
        for each pixel and channel
    """

    try:
        if 'window' not in params or 'shift' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")

    nchan, npix, nsamples = data.shape

    # Define window
    window = params['window']
    start = params['shift']

    # Check window is within readout
    if window > nsamples:
        window = nsamples
    if start < 0:
        start = 0
    if start + window > nsamples:
        start = nsamples - window

    # Select entries
    integration_window = np.zeros_like(data, dtype=bool)
    integration_window[:, :, start:start + window] = True
    windowed_data = data * integration_window

    # Integrate
    integration = np.round(windowed_data.sum(2)).astype(np.int)

    return integration, integration_window, [None, None]
Beispiel #52
0
    def _login(self,
               username=None,
               store_password=False,
               reenter_password=False):
        """
        Login to the ESO User Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ESO Public Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """
        if username is None:
            if self.USERNAME != "":
                username = self.USERNAME
            elif self.username is not None:
                username = self.username
            else:
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
        else:
            # store username as we may need it to re-authenticate
            self.username = username

        # Get password from keyring or prompt
        password, password_from_keyring = self._get_password(
            "astroquery:www.eso.org", username, reenter=reenter_password)

        # Authenticate
        log.info("Authenticating {0} on www.eso.org...".format(username))

        # Do not cache pieces of the login process
        login_response = self._request("GET",
                                       "https://www.eso.org/sso/login",
                                       cache=False)
        root = BeautifulSoup(login_response.content, 'html5lib')
        login_input = root.find(name='input', attrs={'name': 'execution'})
        if login_input is None:
            raise ValueError(
                "ESO login page did not have the correct attributes.")
        execution = login_input.get('value')

        login_result_response = self._request("POST",
                                              "https://www.eso.org/sso/login",
                                              data={
                                                  'username': username,
                                                  'password': password,
                                                  'execution': execution,
                                                  '_eventId': 'submit',
                                                  'geolocation': '',
                                              })
        login_result_response.raise_for_status()
        root = BeautifulSoup(login_result_response.content, 'html5lib')
        authenticated = root.find('h4').text == 'Login successful'

        if authenticated:
            log.info("Authentication successful!")
        else:
            log.exception("Authentication failed!")

        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:www.eso.org", username, password)
        return authenticated
Beispiel #53
0
                else:
                    vrange = [-30, 40]

                for spw in (0, 1, 2, 3):
                    filename = ftemplate.format(spw,
                                                sourcename,
                                                band,
                                                suffix=suffix,
                                                robust=robust,
                                                infix=infix)

                    if os.path.exists(filename):
                        cube = SpectralCube.read(filename)
                        if not cube.wcs.wcs.radesys.lower() == 'icrs':
                            log.exception(
                                "File {0} has wrong coordinate system {1}".
                                format(filename, cube.wcs.wcs.radesys))
                            continue
                    else:
                        log.exception(
                            "File {0} does not exist".format(filename))
                        continue

                    fmin, fmax = cube.spectral_extrema

                    mywcs = cube.wcs.celestial
                    pixscale = wcs.utils.proj_plane_pixel_area(
                        mywcs)**0.5 * u.deg

                    imhalfsize = 0.2 * u.arcsec
                    pixhs = (imhalfsize / pixscale).decompose().value
    '/Volumes/external/orion/Orion{source}_only.B3.robust0.5.spw0.clarkclean10000.image.pbcor.fits',
    '/Volumes/external/orion/Orion{source}_only.B3.robust0.5.spw1.clarkclean10000.image.pbcor.fits',
    '/Volumes/external/orion/Orion{source}_only.B3.robust0.5.spw2.clarkclean10000.image.pbcor.fits',
    '/Volumes/external/orion/Orion{source}_only.B3.robust0.5.spw3.clarkclean10000.image.pbcor.fits',
    '/Volumes/external/orion/Orion{source}_only.B7.robust-2.spw0.maskedclarkclean10000.image.pbcor.fits',
    '/Volumes/external/orion/Orion{source}_only.B7.robust-2.spw1.maskedclarkclean10000.image.pbcor.fits',
    '/Volumes/external/orion/Orion{source}_only.B7.robust-2.spw2.maskedclarkclean10000.image.pbcor.fits',
    '/Volumes/external/orion/Orion{source}_only.B7.robust-2.spw3.maskedclarkclean10000.image.pbcor.fits',
]

for source in ('SourceI', 'BN'):
    for fn in files:
        try:
            cube = SpectralCube.read(fn.format(source=source))
            if cube.wcs.wcs.radesys.lower() == 'fk5':
                log.exception("{0} has radesys = {1}".format(
                    fn.format(source=source), cube.wcs.wcs.radesys))
                continue
            cube = cube.mask_out_bad_beams(0.1)
        except FileNotFoundError:
            log.exception("File {0} not found".format(
                fn.format(source=source)))
            continue

        log.info("Working on file {0}".format(fn.format(source=source)))

        med = cube.median(axis=0)

        medsub = cube - med

        medsub.write(
            fn.replace(".image.pbcor.fits",
Beispiel #55
0
def calibrate_event(event, params, geom_dict=None):
    """
    Generic calibrator for events. Calls the calibrator corresponding to the
    source of the event, and stores the dl1 (pe_charge) information into a
    new event container.

    Parameters
    ----------
    event : container
        A `ctapipe` event container
    params : dict
        REQUIRED:

        params['integrator'] - Integration scheme

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

        OPTIONAL:

        params['integration_clip_amp'] - Amplitude in p.e. above which the
        signal is clipped.

        params['integration_calib_scale'] : Identical to global variable
        CALIB_SCALE in reconstruct.c in hessioxxx software package. 0.92 is
        the default value (corresponds to HESS). The required value changes
        between cameras (GCT = 1.05).

        params['integration_sigamp'] - Amplitude in ADC counts above pedestal
        at which a signal is considered as significant (separate for
        high gain/low gain).
    geom_dict : dict
        Dict of pixel geometry for each telescope. Leave as None for automatic
        calculation when it is required.
        dict[(num_pixels, focal_length)] = `ctapipe.io.CameraGeometry`

    Returns
    -------
    calibrated : container
        A new `ctapipe` event container containing the dl1 information, and a
        reference to all other information contained in the original event
        container.
    """

    # Obtain relevent calibrator
    switch = {
        'hessio':
            partial(mc.calibrate_mc, event=event, params=params)
        }
    try:
        calibrator = switch[event.meta.source]
    except KeyError:
        log.exception("no calibration created for data origin: '{}'"
                      .format(event.meta.source))
        raise

    calibrated = copy(event)

    # Add dl1 to the event container (if it hasn't already been added)
    try:
        calibrated.add_item("dl1", RawData())
        calibrated.dl1.run_id = event.dl0.run_id
        calibrated.dl1.event_id = event.dl0.event_id
        calibrated.dl1.tels_with_data = event.dl0.tels_with_data
        calibrated.dl1.calibration_parameters = params
    except AttributeError:
        pass

    # Fill dl1
    calibrated.dl1.tel = dict()  # clear the previous telescopes
    for telid in event.dl0.tels_with_data:
        nchan = event.dl0.tel[telid].num_channels
        npix = event.dl0.tel[telid].num_pixels
        calibrated.dl1.tel[telid] = CalibratedCameraData(telid)
        calibrated.dl1.tel[telid].num_channels = nchan
        calibrated.dl1.tel[telid].num_pixels = npix

        # Get geometry
        int_dict, inverted = integrator_dict()
        geom = None
        cam_dimensions = (event.dl0.tel[telid].num_pixels,
                          event.meta.optical_foclen[telid])
        # Check if geom is even needed for integrator
        if inverted[params['integrator']] in integrators_requiring_geom():
            if geom_dict is not None and telid in geom_dict:
                geom = geom_dict[telid]
            else:
                log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.meta.pixel_pos[telid],
                                            event.meta.optical_foclen[telid])
                log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[telid] = geom

        pe, window, data_ped, peakpos = calibrator(telid=telid, geom=geom)
        calibrated.dl1.tel[telid].pe_charge = pe
        calibrated.dl1.tel[telid].peakpos = peakpos
        for chan in range(nchan):
            calibrated.dl1.tel[telid].integration_window[chan] = window[chan]
            calibrated.dl1.tel[telid].pedestal_subtracted_adc[chan] = \
                data_ped[chan]

    return calibrated
Beispiel #56
0
def set_integration_correction(event, telid, params):
    """
    Obtain the integration correction for the window specified

    Parameters
    ----------
    event : container
        A `ctapipe` event container
    telid : int
        telescope id
    params : dict
        REQUIRED:

        params['integration_window'] - Integration window size and shift of
        integration window centre

        (adapted such that window fits into readout).

    Returns
    -------
    correction : float
        Value of the integration correction for this instrument \n
    """

    try:
        if 'integration_window' not in params:
            raise KeyError()
    except KeyError:
        log.exception("[ERROR] missing required params")
        raise

    tel =  event.dl0.tel[telid]
    mctel = event.mc.tel[telid]
    num_channels = event.inst.num_channels[telid]
    num_samples = event.inst.num_samples[telid]

    # Reference pulse parameters
    refshapes = np.array(list(mctel.reference_pulse_shape.values()))
    refstep = mctel.meta['refstep']
    nrefstep = len(refshapes[0]) # mctel.lrefshape
    x = np.arange(0, refstep*nrefstep, refstep)
    y = refshapes[num_channels-1]
    refipeak = np.argmax(y)

    # Sampling pulse parameters
    time_slice = mctel.time_slice
    x1 = np.arange(0, refstep*nrefstep, time_slice)
    y1 = interp(x1, x, y)
    ipeak = np.argmin(np.abs(x1-x[refipeak]))

    # Check window is within readout
    window = params['integration_window'][0]
    shift = params['integration_window'][1]
    start = ipeak - shift
    if window > num_samples:
        window = num_samples
    if start < 0:
        start = 0
    if start + window > num_samples:
        start = num_samples - window

    correction = round((sum(y) * refstep) / (sum(y1[start:start + window]) *
                                             time_slice), 7)

    return correction
Beispiel #57
0
    def _login(self, username=None, store_password=False,
               reenter_password=False):
        """
        Login to the ALMA Science Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ALMA Science Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """

        if username is None:
            if self.USERNAME == "":
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Check if already logged in
        loginpage = self._request("GET", "https://asa.alma.cl/cas/login",
                                  cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        # Get password from keyring or prompt
        if reenter_password is False:
            password_from_keyring = keyring.get_password(
                "astroquery:asa.alma.cl", username)
        else:
            password_from_keyring = None

        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warning("You may be using an ipython notebook:"
                            " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your ALMA password:"******"\n".format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on asa.alma.cl ...".format(username))
        # Do not cache pieces of the login process
        data = {kw: root.find('input', {'name': kw})['value']
                for kw in ('lt', '_eventId', 'execution')}
        data['username'] = username
        data['password'] = password

        login_response = self._request("POST", "https://asa.alma.cl/cas/login",
                                       params={'service':
                                               urljoin(self.archive_url,
                                                       'rh/login')},
                                       data=data,
                                       cache=False)

        authenticated = ('You have successfully logged in' in
                         login_response.text)

        if authenticated:
            log.info("Authentication successful!")
            self._username = username
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:asa.alma.cl", username, password)
        return authenticated
Beispiel #58
0
    def _login(self, username=None, store_password=False,
               reenter_password=False):
        """
        Login to the ESO User Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ESO Public Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """
        if username is None:
            if self.USERNAME == "":
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Get password from keyring or prompt
        if reenter_password is False:
            password_from_keyring = keyring.get_password(
                "astroquery:www.eso.org", username)
        else:
            password_from_keyring = None

        if password_from_keyring is None:
            if system_tools.in_ipynb():
                log.warning("You may be using an ipython notebook:"
                            " the password form will appear in your terminal.")
            password = getpass.getpass("{0}, enter your ESO password:\n"
                                       .format(username))
        else:
            password = password_from_keyring
        # Authenticate
        log.info("Authenticating {0} on www.eso.org...".format(username))

        # Do not cache pieces of the login process
        login_response = self._request("GET", "https://www.eso.org/sso/login",
                                       cache=False)
        root = BeautifulSoup(login_response.content, 'html5lib')
        login_input = root.find(name='input', attrs={'name': 'execution'})
        if login_input is None:
            raise ValueError("ESO login page did not have the correct attributes.")
        execution = login_input.get('value')

        login_result_response = self._request("POST", "https://www.eso.org/sso/login",
                                              data={'username': username,
                                                    'password': password,
                                                    'execution': execution,
                                                    '_eventId': 'submit',
                                                    'geolocation': '',
                                                    })
        login_result_response.raise_for_status()
        root = BeautifulSoup(login_result_response.content, 'html5lib')
        authenticated = root.find('h4').text == 'Login successful'

        if authenticated:
            log.info("Authentication successful!")
        else:
            log.exception("Authentication failed!")

        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:www.eso.org", username, password)
        return authenticated
    for band, suffix in (('B3', 'clarkclean10000'), ('B6',
                                                     'maskedclarkclean10000')):
        for sourcename in ('SourceI', ):  # 'BN'):

            for spw in (0, 1, 2, 3):
                filename = ftemplate.format(spw,
                                            sourcename,
                                            band,
                                            suffix=suffix,
                                            robust=robust)

                if os.path.exists(filename):
                    cube = SpectralCube.read(filename).mask_out_bad_beams(0.1)
                else:
                    log.exception("File {0} does not exist".format(filename))
                    continue

                fmin, fmax = cube.spectral_extrema
                dv = np.mean(
                    np.diff(
                        cube.with_spectral_unit(u.km / u.s,
                                                velocity_convention='radio',
                                                rest_value=(fmin + fmax) /
                                                2.).spectral_axis))

                noise = cube.mad_std()
                average_beam = cube.average_beams(0.1)

                row = (r"{band} & {spw} & {freq1:0.3f}-{freq2:0.3f} & "
                       r"{robust} & {bmaj:0.3f} & {bmin:0.3f} & {bpa:0.1f} & "