Example #1
0
def distance(n1, n2):
    """Calculate distance in km between two nodes"""
    lat1, lon1 = n1[0], n1[1]
    lat2, lon2 = n2[0], n2[1]
    delta_lat = lat2 - lat1
    delta_lon = lon2 - lon1
    d = math.sin(math.radians(delta_lat) * 0.5) ** 2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) \
        * math.sin(math.radians(delta_lon) * 0.5) ** 2
    return math.asin(math.sqrt(d)) * 12742
 def _get_alpha(self):
     if abs(self.dec) + self.radius > 89.9:
         return 180
     return math.degrees(
         abs(
             math.atan(
                 math.sin(math.radians(self.radius)) / np.sqrt(
                     abs(
                         math.cos(math.radians(self.dec - self.radius)) *
                         math.cos(math.radians(self.dec + self.radius)))))))
def get_alpha(radius, dec):
    if abs(dec) + radius > 89.9:
        return 180
    return math.degrees(
        abs(
            math.atan(
                math.sin(math.radians(radius)) / np.sqrt(
                    abs(
                        math.cos(math.radians(dec - radius)) *
                        math.cos(math.radians(dec + radius)))))))
    def Evolvent(self):
        '''Расчет эвольвенты зуба
        '''
        #Расчет эвольветы зуба 
        # Читаем данные из полей формы
        # z = Количество зубьев
        z = self.doubleSpinBox_Z.value() 
        # m = Модуль зуба
        m = self.doubleSpinBox_m.value() 
        # a = Угол главного профиля
        a = self.doubleSpinBox_a.value()
        #b = Угол наклона зубьев
        b = self.doubleSpinBox_b.value()
        #ha = Коэффициент высоты головки
        ha = self.doubleSpinBox_ha.value()
        #pf = К-т радиуса кривизны переходной кривой
        pf = self.doubleSpinBox_pf.value()
        #c = Коэффициент радиального зазора
        c = self.doubleSpinBox_c.value()
        #x = К-т смещения исходного контура
        x = self.doubleSpinBox_x.value()
        #y =Коэффициент уравнительного смещения
        y = self.doubleSpinBox_y.value()
        # n= Количество точек (точность построения)
        #n=int(self.doubleSpinBox_n.value())
        n=100
        # заполня переменные 
        # Делительный диаметр
        d = z * m
        # Высота зуба h=
        h = 2.25 * m
        # Высота головки ha =
        hav = m
        # Высота ножки hf=
        hf = 1.25 * m
        #Диаметр вершин зубьев
        #da = d + (2 * m)*(ha+x+y)
        da = d + 2 * (ha + x - y) * m
        #Диаметр впадин (справочно)
        #df = d -(2 * hf)
        df = d -2 * (ha + c - x) * m
        #Окружной шаг зубьев или Шаг зацепления по дуге делительной окружности: Pt или p
        pt = math.pi * m
        #Окружная толщина зуба или Толщина зуба по дуге делительной окружности: St или S
        #Суммарный коэффициент смещений: XΣ
        X = 0.60 + 0.12
       # St = 0.5 * pf
       # St = 0.5 * pt
        St = 0.5 * pt + 2 * x * m * math.tan(math.radians(a))
        #inv a 
        inva=math.tan(math.radians(a))-math.radians(a)
        #Угол зацепления invαw
        invaw= (2 * X - math.tan(math.radians(a))) / (10+26) + inva
        #Угол профиля
        at = math.ceil(math.degrees(math.atan(math.tan(math.radians(a))
            /math.cos( math.radians(b)))))
        # Диаметр основной окружности
        db = d * math.cos(math.radians(at)) 
        #Диаметр начала выкружки зуба
        D  = 2 * m * ( ( z/( 2 * math.cos(math.radians(b)) )-(1-x)) ** 2 +
            ((1-x)/math.tan(math.radians(at)))**2)**0.5
        #Промежуточные данные
        yi = math.pi/2-math.radians(at)

        hy = yi/(n-1)

        x0 = math.pi/(4*math.cos(math.radians(b))
             )+pf*math.cos(math.radians(at))+math.tan(math.radians(at))

        y0 = 1-pf*math.sin(math.radians(at))-x

        C  = (math.pi/2+2*x*math.tan(math.radians(a))
             )/z+math.tan(math.radians(at))-math.radians(at)
        #Расчетный шаг точек эвольвенты
        hdy = (da-D)/(n-1)
        dyi = da
        fi = 2*math.cos(math.radians(b))/z*(x0+y0*math.tan(yi))
        #Заполняем текстовые поля в форме
        # Делительный диаметр
    #    self.lineEdit_d.setText(str(d))
        # Высота зуба h=
    #    self.lineEdit_h.setText(str(h))
        # Высота головки ha =
    #    self.lineEdit_ha.setText(str(hav))
        # Высота ножки hf=
    #    self.lineEdit_hf.setText(str(hf))
        # Диаметр вершин зубьев
    #    self.lineEdit_da.setText(str(da))
        # Диаметр впадин (справочно)
    #    self.lineEdit_df.setText(str(df))
        # Окружной шаг зубьев Pt=
    #    self.lineEdit_Pt.setText(str(math.ceil(pt)))
        # Окружная толщина зуба St=
    #    self.lineEdit_St.setText(str(math.ceil(St)))
        # Угол профиля
    #    self.lineEdit_at.setText(str(at))
        # Диаметр основной окружности
    #    self.lineEdit_db.setText(str(math.ceil(db)))
        
        # Создаем списки 
        List_dyi=[]
        List_Di=[]
        List_Yei=[]
        List_Xei=[]
        List_Minus_Xei=[]
        List_Xdai=[]
        List_Ydai=[]
        List_yi=[]
        List_Ai=[]
        List_Bi=[]
        List_fi=[]
        List_Ypki=[]
        List_Xpki=[]
        List_Minus_Xpki=[]
        # Заполняем нуливой (первый )индекс списка значениями
        List_dyi.append(dyi)
        List_Di.append( math.acos( db/ List_dyi[0] ) - math.tan( math.acos( db / List_dyi[0] ) ) + C )
        List_Yei.append(dyi / 2*math.cos( List_Di[0]))
        List_Xei.append(List_Yei[0]*math.tan(List_Di[0]))
        List_Minus_Xei.append(-List_Xei[0])
        List_Xdai.append(-List_Xei[0])
        List_Ydai.append(((da/2)**2-List_Xdai[0]**2)**0.5)
        hda=(List_Xei[0]-List_Minus_Xei[0])/(n-1)
        # Заполняем первый (второй по счету )индекс списка значениями 
        List_dyi.append(dyi-hdy)
        List_Di.append( math.acos(db/List_dyi[1])-math.tan(math.acos(db/List_dyi[1]))+C)
        List_Yei.append( List_dyi[1]/2*math.cos(List_Di[1]))
        List_Xei.append( List_Yei[1]* math.tan(List_Di[1]))
        List_Minus_Xei.append(-List_Xei[1])
        List_Xdai.append(List_Xdai[0]+hda)
        List_Ydai.append(((da/2)**2-List_Xdai[1]**2)**0.5)
        Xdai=List_Xdai[1]
        dyi=dyi-hdy
        # Начинаем  заполнять списки в цикле 
        i=0
        while i < n-2:  
            i=i+1
            dyi=dyi-hdy
            List_Di.append(math.acos(db/dyi)-math.tan(math.acos(db/dyi))+C)
            Di=math.acos(db/dyi)-math.tan(math.acos(db/dyi))+C
            Yei=dyi/2*math.cos(Di)
            Xei=Yei*math.tan(Di) 
            List_dyi.append(dyi) 
            List_Yei.append(dyi/2*math.cos(Di))
            List_Xei.append(Yei*math.tan(Di))
            List_Minus_Xei.append(-Xei) 
            Xdai=Xdai+hda
            List_Xdai.append(Xdai)
            List_Ydai.append(((da/2)**2-Xdai**2)**0.5)
        #Заполняем последний индекс  списка    
        List_dyi[n-1]=D
        # Заполняем нуливой (первый )индекс списка значениями
        List_yi.append(yi)
        List_Ai.append(z/(2*math.cos(math.radians(b)))-y0-pf*math.cos(List_yi[0]) )
        List_Bi.append(y0*math.tan(List_yi[0])+pf*math.sin(List_yi[0]))
        List_fi.append(fi)
        List_Ypki.append((List_Ai[0] * math.cos(fi)+List_Bi[0] * math.sin(fi)) * m)
        List_Xpki.append((List_Ai[0] * math.sin(fi)-List_Bi[0] * math.cos(fi)) * m)
        List_Minus_Xpki.append(-List_Xpki[0])
        # Начинаем  заполнять списки в цикле 
        i=0
        while i < n-2:
            i=i+1
            yi=yi-hy
            List_yi.append(yi)
            Ai = z / (2 * math.cos(math.radians(b)))-y0-pf*math.cos(yi)
            List_Ai.append( z / (2 * math.cos(math.radians(b)))-y0-pf*math.cos(yi))
            Bi =y0*math.tan(yi)+pf*math.sin(yi)
            List_Bi.append(y0*math.tan(yi)+pf*math.sin(yi))
            fi = 2*math.cos(math.radians(b))/z*(x0+y0*math.tan(yi))
            List_fi.append(2*math.cos(math.radians(b))/z*(x0+y0*math.tan(yi)))
            List_Ypki.append((Ai*math.cos(fi)+Bi*math.sin(fi))*m)
            Ypki=(Ai*math.cos(fi)+Bi*math.sin(fi))*m
            Xpki=(Ai*math.sin(fi)-Bi*math.cos(fi))*m
            List_Xpki.append((Ai*math.sin(fi)-Bi*math.cos(fi))*m)
            List_Minus_Xpki.append(-Xpki)
        #Заполняем последний индекс  списка  
        List_yi.append(yi-yi)
        List_Ai.append(z/(2*math.cos(math.radians(b)))-y0-pf*math.cos(List_yi[n-1]) )  
        List_Bi.append(y0*math.tan(List_yi[n-1])+pf*math.sin(List_yi[n-1])) 
        List_fi.append(2*math.cos(math.radians(b))/z*(x0+y0*math.tan(List_yi[n-1])))
        List_Ypki.append((List_Ai[n-1] * math.cos(fi)+List_Bi[n-1] * math.sin(List_fi[n-1])) * m)
        List_Xpki.append((List_Ai[n-1] * math.sin(fi)-List_Bi[n-1] * math.cos(List_fi[n-1])) * m)
        List_Minus_Xpki.append(-List_Xpki[n-1])

       # self.WiPfileZub(List_Yei,List_Xei,List_Minus_Xei,List_Ypki,List_Xpki,List_Minus_Xpki,List_Ydai,List_Xdai)
        self.GragEvolvent(List_Minus_Xei+List_Minus_Xpki,List_Yei+List_Ypki,n)

        DFreza = self.lineEditDFreza.text()
        VisotaYAxis = self.lineEditVisota.text()
        Diametr = self.lineEditDiametr.text()
        if DFreza and VisotaYAxis:
            E30 = (int(DFreza)/2) +float(VisotaYAxis)
        else:
            E30 = 0
        angi_B=0
        if ValkosZub:
            angie_A:float = 90# угол А треугольника по высоте детали 
            angie_B:float = float(b) #угол B треугольника по высоте детали ( угол наклона зуба по чертежу)
            angie_Y:float = 180 - (angie_A + angie_B) # трерий уго треугольника по высоте детали 
            side_c:float = float(E30)# высота детали первая сторона треугольника 
            side_a = side_c * math.sin(math.radians(angie_A)) / math.sin(math.radians(angie_Y))# вторая сторона треугольника 
            side_b = side_c * math.sin(math.radians(angie_B)) / math.sin(math.radians(angie_Y))# третия сторона треугольника ( ось Х)
            sid_a:float = float(Diametr)/2 # радиус детали первая и вторая тророны треугольника по торцу
           # sid_a:float = float(self.lineEdit_da.text())/2 # радиус детали первая и вторая тророны треугольника по торцу
            sid_c:float = sid_a
            if sid_c < 10 :
                sid_a:float = 10
                sid_c:float = 10
                angi_B = float('{:.3f}'.format(math.degrees(math.acos((sid_a**2+sid_c**2-side_b**2)/(2*sid_a*sid_c)))))
                QMessageBox.about (self, "Ошибка " , "Диаметр шестерни задан меньше 20 мм. \n Введите риальный диаметр шестерни " )
            else:
                angi_B = float('{:.3f}'.format(math.degrees(math.acos((sid_a**2+sid_c**2-side_b**2)/(2*sid_a*sid_c)))))# результат угол поворота стола 


        self.label_da.setText(str(round(da,1)))
        self.label_d.setText(str(round(d,1)))
        self.label_at.setText(str(round(at,1)))
        self.label_db.setText(str(round(db,1)))
        self.label_df.setText(str(round(df,1)))
        self.label_St.setText(str(round(St,1)))
        self.label_Pt.setText(str(round(pt,1)))
        self.label_hf.setText(str(round(hf,1)))
        self.label_ha.setText(str(round(ha,1)))
        self.label_h.setText(str(round(h,1)))
        self.lineEditDiametr.setText(str(da))
        self.lineEditUgol.setText(str(angi_B))
    def __init__(self,
                 ra,
                 dec,
                 radius,
                 time_start,
                 time_end,
                 flag,
                 aws_profile,
                 aws_region,
                 s3_output_location,
                 local_output_location,
                 athena_database,
                 athena_workgroup,
                 query_life=10,
                 wait_time=0.1,
                 single_query=True):
        self.ra = ra
        self.dec = dec
        self.radius = radius
        self.time_start = time_start
        self.time_end = time_end
        self.flag = flag
        self.s3_output_location = s3_output_location
        self.local_output_location = local_output_location
        self.athena_database = athena_database
        self.athena_workgroup = athena_workgroup
        self.query_life = query_life
        self.wait_time = wait_time
        self.single_query = single_query
        sess = boto3.Session(profile_name=aws_profile, region_name=aws_region)
        global athena_client, s3_client
        athena_client = sess.client('athena')
        s3_client = sess.client('s3')
        self.s3_output_path = s3_output_location.replace('s3://',
                                                         '').split('/')
        self.bucket = self.s3_output_path[0]
        self.additional_s3_path = s3_output_location.replace(
            's3://{}/'.format(self.bucket), '')
        self.query = '''
                SELECT *
                FROM gPhoton_partitioned
                WHERE zoneID = {}
                AND dec BETWEEN {} AND {}
                AND ra BETWEEN {} AND {}
                AND ({}*cx + {}*cy + {}*cz) > {}
                AND time >= {} AND time < {}
                AND flag = {};
            '''

        # calculate_query_parameters
        self.cx = math.cos(math.radians(self.dec)) * math.cos(
            math.radians(self.ra))
        self.cy = math.cos(math.radians(self.dec)) * math.sin(
            math.radians(self.ra))
        self.cz = math.sin(math.radians(self.dec))
        self.alpha = self._get_alpha()
        if (self.ra - self.alpha) < 0:
            self.ra = self.ra + 360
        self.zoneHeight = 30.0 / 3600.0
        self.min_zoneid = int(
            np.floor((self.dec - self.radius + 90.0) / self.zoneHeight))
        self.max_zoneid = int(
            np.floor((self.dec + self.radius + 90.0) / self.zoneHeight))

        self.query_args_collection = {
            'non-conditional': [
                self.dec - self.radius, self.dec + self.radius,
                self.ra - self.alpha, self.ra + self.alpha, self.cx, self.cy,
                self.cz,
                math.cos(math.radians(self.radius)), self.time_start,
                self.time_end, self.flag
            ],
            'conditional': [
                self.dec - self.radius, self.dec + self.radius, 0,
                self.ra - 360 + self.alpha, self.cx, self.cy, self.cz,
                math.cos(math.radians(self.radius)), self.time_start,
                self.time_end, self.flag
            ]
        }
Example #6
0
    def vinc_inv(f, a, coordinate_a, coordinate_b):
        """

        Returns the distance between two geographic points on the ellipsoid
        and the forward and reverse azimuths between these points.
        lats, longs and azimuths are in radians, distance in metres

        :param f: flattening of the geodesic
        :param a: the semimajor axis of the geodesic
        :param coordinate_a: decimal coordinate given as named tuple coordinate
        :param coordinate_b: decimal coordinate given as named tuple coordinate
        Note: The problem calculates forward and reverse azimuths as: coordinate_a -> coordinate_b

        """
        phi1 = math.radians(coordinate_a.lat)
        lembda1 = math.radians(coordinate_a.lon)

        phi2 = math.radians(coordinate_b.lat)
        lembda2 = math.radians(coordinate_b.lon)

        if (abs(phi2 - phi1) < 1e-8) and (abs(lembda2 - lembda1) < 1e-8):
            return {'distance': 0.0, 'forward_azimuth': 0.0, 'reverse_azimuth': 0.0}

        two_pi = 2.0 * math.pi

        b = a * (1 - f)

        TanU1 = (1 - f) * math.tan(phi1)
        TanU2 = (1 - f) * math.tan(phi2)

        U1 = math.atan(TanU1)
        U2 = math.atan(TanU2)

        lembda = lembda2 - lembda1
        last_lembda = -4000000.0  # an impossibe value
        omega = lembda

        # Iterate the following equations,
        #  until there is no significant change in lembda

        while (last_lembda < -3000000.0 or lembda != 0 and abs((last_lembda - lembda) / lembda) > 1.0e-9):
            sqr_sin_sigma = pow(math.cos(U2) * math.sin(lembda), 2) + \
                            pow((math.cos(U1) * math.sin(U2) -
                                 math.sin(U1) * math.cos(U2) * math.cos(lembda)), 2)

            Sin_sigma = math.sqrt(sqr_sin_sigma)

            Cos_sigma = math.sin(U1) * math.sin(U2) + math.cos(U1) * math.cos(U2) * math.cos(lembda)

            sigma = math.atan2(Sin_sigma, Cos_sigma)

            Sin_alpha = math.cos(U1) * math.cos(U2) * math.sin(lembda) / math.sin(sigma)
            alpha = math.asin(Sin_alpha)

            Cos2sigma_m = math.cos(sigma) - (2 * math.sin(U1) * math.sin(U2) / pow(math.cos(alpha), 2))

            C = (f / 16) * pow(math.cos(alpha), 2) * (4 + f * (4 - 3 * pow(math.cos(alpha), 2)))

            last_lembda = lembda

            lembda = omega + (1 - C) * f * math.sin(alpha) * (sigma + C * math.sin(sigma) * \
                                                              (Cos2sigma_m + C * math.cos(sigma) * (
                                                                  -1 + 2 * pow(Cos2sigma_m, 2))))

        u2 = pow(math.cos(alpha), 2) * (a * a - b * b) / (b * b)

        A = 1 + (u2 / 16384) * (4096 + u2 * (-768 + u2 * (320 - 175 * u2)))

        B = (u2 / 1024) * (256 + u2 * (-128 + u2 * (74 - 47 * u2)))

        delta_sigma = B * Sin_sigma * (Cos2sigma_m + (B / 4) * \
                                       (Cos_sigma * (-1 + 2 * pow(Cos2sigma_m, 2)) - \
                                        (B / 6) * Cos2sigma_m * (-3 + 4 * sqr_sin_sigma) * \
                                        (-3 + 4 * pow(Cos2sigma_m, 2))))

        s = b * A * (sigma - delta_sigma)

        alpha12 = math.atan2((math.cos(U2) * math.sin(lembda)), \
                             (math.cos(U1) * math.sin(U2) - math.sin(U1) * math.cos(U2) * math.cos(lembda)))

        alpha21 = math.atan2((math.cos(U1) * math.sin(lembda)), \
                             (-math.sin(U1) * math.cos(U2) + math.cos(U1) * math.sin(U2) * math.cos(lembda)))

        if (alpha12 < 0.0):
            alpha12 += two_pi
        if (alpha12 > two_pi):
            alpha12 -= two_pi

        alpha21 += two_pi / 2.0
        if alpha21 < 0.0:
            alpha21 += alpha21 + two_pi
        if alpha21 > two_pi:
            alpha21 -= two_pi

        return {"distance": s, "forward_azimuth": alpha12, "reverse_azimuth": alpha21}
def cone_search(ra,
                dec,
                radius,
                time_start,
                time_end,
                flag,
                aws_profile,
                aws_region,
                s3_output_location,
                local_output_location,
                athena_database,
                athena_workgroup,
                query_life=10,
                wait_time=0.1,
                single_query=True):
    def query_athena(query, query_args):
        query = query.format(*query_args)
        response = athena_client.start_query_execution(
            QueryString=query,
            QueryExecutionContext={'Database': athena_database},
            ResultConfiguration={'OutputLocation': s3_output_location},
            WorkGroup=athena_workgroup)
        print('Query submitted:\n{}\n'.format(query))
        rsp = athena_client.get_query_execution(
            QueryExecutionId=response['QueryExecutionId'])
        succeeded_query = True if rsp['QueryExecution']['Status'][
            'State'] == 'SUCCEEDED' else False
        num_sec_query_has_been_running = 0
        # check to see if the query has succeeded
        while not succeeded_query:
            if num_sec_query_has_been_running >= query_life:
                print(
                    'QUERY CANCELLED: Query {} has been running for ~{} seconds.'
                    .format(response['QueryExecutionId'],
                            num_sec_query_has_been_running))
                _ = athena_client.stop_query_execution(
                    QueryExecutionId=response['QueryExecutionId'])
                return None
            if num_sec_query_has_been_running % 60 == 0 and num_sec_query_has_been_running:
                duration = int(num_sec_query_has_been_running / 60)
                word = 'minutes' if duration > 1 else 'minute'
                print('...Query has been running for ~{} {}.'.format(
                    duration, word))
            # wait until query has succeeded to start the next query
            if num_sec_query_has_been_running + wait_time > query_life:
                sleep_time = query_life - num_sec_query_has_been_running
            else:
                sleep_time = wait_time
            time.sleep(sleep_time)
            num_sec_query_has_been_running += sleep_time
            rsp = athena_client.get_query_execution(
                QueryExecutionId=response['QueryExecutionId'])
            succeeded_query = True if rsp['QueryExecution']['Status'][
                'State'] == 'SUCCEEDED' else False
        return response['QueryExecutionId']

    sess = boto3.Session(profile_name=aws_profile, region_name=aws_region)
    athena_client = sess.client('athena')
    s3_client = sess.client('s3')
    s3_output_path = s3_output_location.replace('s3://', '').split('/')
    bucket = s3_output_path[0]
    additional_s3_path = s3_output_location.replace('s3://{}/'.format(bucket),
                                                    '')
    queries = {
        'single':
        '''
            SELECT *
            FROM gPhoton_partitioned
            WHERE zoneID BETWEEN {} AND {}
                AND dec BETWEEN {} AND {}
                AND ra BETWEEN {} AND {}
                AND ({}*cx + {}*cy + {}*cz) > {}
                AND time >= {} AND time < {}
                AND flag = {};
         ''',
        'multiple':
        '''
            SELECT *
            FROM gPhoton_partitioned
            WHERE zoneID = {}
                AND dec BETWEEN {} AND {}
                AND ra BETWEEN {} AND {}
                AND ({}*cx + {}*cy + {}*cz) > {}
                AND time >= {} AND time < {}
                AND flag = {};
         '''
    }

    cx = math.cos(math.radians(dec)) * math.cos(math.radians(ra))
    cy = math.cos(math.radians(dec)) * math.sin(math.radians(ra))
    cz = math.sin(math.radians(dec))
    alpha = get_alpha(radius, dec)
    if (ra - alpha) < 0:
        ra = ra + 360
    zoneHeight = 30.0 / 3600.0
    min_zoneid = int(np.floor((dec - radius + 90.0) / zoneHeight))
    max_zoneid = int(np.floor((dec + radius + 90.0) / zoneHeight))

    query_args_collection = {
        'non-conditional': [
            dec - radius, dec + radius, ra - alpha, ra + alpha, cx, cy, cz,
            math.cos(math.radians(radius)), time_start, time_end, flag
        ],
        'conditional': [
            dec - radius, dec + radius, 0, ra - 360 + alpha, cx, cy, cz,
            math.cos(math.radians(radius)), time_start, time_end, flag
        ]
    }

    query_collection = ''
    query_argument_collection = []
    for zoneid in range(min_zoneid, max_zoneid + 1):
        query = queries['single'] if single_query else queries['multiple']
        zone_args = [min_zoneid, max_zoneid] if single_query else [zoneid]
        query_args = zone_args + query_args_collection['non-conditional']
        if (ra + alpha) > 360:
            query = query.replace(';',
                                  '') + '\n            UNION ALL\n' + query
            additional_args = [min_zoneid, max_zoneid
                               ] if single_query else [zoneid]
            query_args = query_args + additional_args + query_args_collection[
                'conditional']
        temp_query = query.replace(
            ';', ''
        ) + '\n            UNION ALL\n' if not single_query and zoneid != max_zoneid else query
        query_collection += temp_query
        query_argument_collection.extend(query_args)
        if single_query:
            break
    start_time = time.time()
    execution_id = query_athena(query_collection, query_argument_collection)
    print('Time taken to query: ~{:.4f} seconds'.format(time.time() -
                                                        start_time))

    # get single CSV or accumulate the CSVs from the different SELECT statements
    dfs = []
    download_paths = []
    if execution_id is not None:
        path_to_csv = os.path.join(additional_s3_path, execution_id + '.csv')
        download_path = os.path.join(local_output_location,
                                     execution_id + '.csv')
        start_time = time.time()
        s3_client.download_file(bucket, path_to_csv, download_path)
        print('Time taken to download: ~{:.4f} seconds'.format(time.time() -
                                                               start_time))
        dfs.append(pd.read_csv(download_path, engine='python'))
        download_paths.append(download_path)
    if len(dfs):
        df = pd.concat(dfs)
        output_location = os.path.join(local_output_location,
                                       str(uuid4()) + '.csv')
        df.to_csv(output_location, index=False)
        print('\nData written to {}\n'.format(output_location))
        for download_path in download_paths:
            os.remove(download_path)
        print(df.head())
    else:
        print('No CSVs were found.')