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
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
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
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
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
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
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
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
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)
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
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)
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
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
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
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
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
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)
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
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
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)
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
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
): 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, # )
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
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)))
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
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
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]
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
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)
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
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
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
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 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
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
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
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
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
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]
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
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",
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
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
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
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} & "