diff --git a/IR_image_tools.py b/IR_image_tools.py
index 92342946174c0a43a1c427257c4270d972c81943..5123913a49902892786fa870d97deb8e8032a65c 100644
--- a/IR_image_tools.py
+++ b/IR_image_tools.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
 Created on Wed May  9 14:56:32 2018
-Version: 3.3.0
+Version: 3.3.2
 @author: Holger Niemann, Peter Drewelow, Yu Gao
 
 mainly to clean up the downloadversionIRdata code
@@ -521,6 +521,33 @@ def check_dublicates_2(array):
             seen.add(x)
     return uniq,seen
 
+def get_work_list(pipepath,typ="q"):
+    """
+    """
+    today=datetime.datetime.now()    
+    cam_programs=[]
+    if typ=='q' or typ=='load':
+        f=open(pipepath+str(today.year)+str(today.month)+"_"+typ+"_requests.txt")
+    else:
+        reasons=[]
+        f=open(pipepath+"problematic_programs.txt")
+    for line in f:
+        koline=line.split("\t")
+        if len(koline)>1:
+            prog=koline[0]
+            if typ=='q' or typ=='load':
+                cam_programs.append((prog,koline[1].split("\n")[0]))    
+            else:
+                cam_programs.append((prog,koline[1]))                    
+                reasons.append(koline[2].split("\n")[0])
+    f.close()
+    if typ=='q' or typ=='load':
+        bla=check_dublicates_2(cam_programs)
+        cam_programs=bla[0]
+        return cam_programs
+    else:
+        return cam_programs,reasons
+
 #%% functions regarding wetted area calculation
 
 def read_finger_info(file_name=None, OP='OP1.2b', verbose=0):
@@ -630,7 +657,7 @@ def derive_wetted_area_per_module(heat_flux, mapping, mode='average', q_max=None
            noise_threshold: float, optional
                minimum heat flux level to crop heat_flux to, if heat flux has negative values
                (OPTIONAL: default is 200kW/m²)
-           ports_loaded: list or str or int, optinal
+           ports_loaded: list or str or int, optional if mode not 'average'
                label of divertor modules provided in heat_flux array for plots; 
                int of port number for single divertor data and list of 
                port numbers for heat flux from multiple divertor modules; #
@@ -655,12 +682,23 @@ def derive_wetted_area_per_module(heat_flux, mapping, mode='average', q_max=None
                * 3D: heat flux from multiple divertor modules
            and the mode to derive q_max ('module', 'average', 'finger'):
                * '2D' + 'module' or 'average' --> one value for total_wetted_area and q_max
-               * '3D' + 'average' --> one value for total_wetted_area and q_max
+               * '3D' + 'average' --> 1D numpy arrays with two values for total_wetted_area and q_max (upper and lower divertors)
                * '3D' + 'module' --> 1D numpy arays with a value for each torus module (first dimension of heat_flux)
                * '2D' + 'finger' --> 1D numpy arays with a value for each divertor finger
                * '3D' + 'finger' --> 2D numpy arays with a value for each torus module and each divertor finger
     '''
-    
+    #check input
+    heat_flux_dim = len(np.shape(heat_flux))
+    if mode == 'average' and ports_loaded == None and heat_flux_dim>2:
+        raise Exception("derive_wetted_area_per_module: ports must be specified in average mode since V3.3.2")
+    elif mode == 'average' and heat_flux_dim>2:
+        try:
+            llen=len(ports_loaded)
+        except:
+            raise Exception("derive_wetted_area_per_module: each divertor need a description to calcualte proper the wetted area!")
+        else:
+            if llen!=len(heat_flux):
+                raise Exception("derive_wetted_area_per_module: number of given divertors and number of descriptions does not match!")
     # prepare mapping and finger information
     finger_dic = read_finger_info(verbose=verbose-1)
     finger_ID = finger_dic['ID']
@@ -682,14 +720,31 @@ def derive_wetted_area_per_module(heat_flux, mapping, mode='average', q_max=None
         if verbose>0:
             print('derive_wetted_area_per_module: set heat_flux < {0:.1f}kW/m² to 0'.format(noise_threshold/1E3))
             
-    heat_flux_dim = len(np.shape(heat_flux))
+    
     # reduce dimension of heat_flux if in 'average' mode
     if heat_flux_dim == 2 and mode == 'average':
         mode = 'module'
     elif heat_flux_dim == 3 and mode == 'average':
-        heat_flux = np.nanmean(heat_flux, axis=0)
-        heat_flux_dim = 2
-        ports_loaded = 'mean heat flux'
+#        heat_flux = np.nanmean(heat_flux, axis=0)
+        ## sort the divertors
+        updiv=([])
+        downdiv=[]
+        for i in range(len(ports_loaded)):
+            # entries in the array/list are either int or str or even float
+            try:
+                port=int(ports_loaded[i])
+            except: #okay it is not an int or an int like string
+                ## what can it be? 'AEFXX'? But what about OP2 with the A or K ports? Still be 3 letters
+                port=int(ports_loaded[i][3:])
+            if port%10==0:
+                downdiv.append(heat_flux[i])
+            else:
+                updiv.append(heat_flux[i])
+        heat_flux=np.array([np.nanmean(np.asarray(updiv),axis=0),np.nanmean(np.asarray(downdiv),axis=0)])
+        del downdiv,updiv
+#        heat_flux_dim = 3
+        ports_loaded = ['upper divertor','lower divertor']#'mean heat flux'
+        mode = 'module'
         if verbose>0:
             print('derive_wetted_area_per_module: averaged 3D heat flux array over first dimension')
     
diff --git a/downloadversionIRdata.py b/downloadversionIRdata.py
index 7e4be7286ac26d5f5a111859018912f158494384..809d3b9909916f1fe47780f90ce28105bd7ad177 100644
--- a/downloadversionIRdata.py
+++ b/downloadversionIRdata.py
@@ -460,13 +460,15 @@ def download_hot_cold_reference_by_times(port,exposure,starttime=150390720000000
     Uses first calibration frames if time is not defined.
     """
     OP=IR_tools.get_OP_by_time(time_ns=starttime)
+    if isinstance(port,int):
+        port="AEF"+str(port)
     if testmode:
-        larchivepath=testarchivepath+project+"/"+portpathdict[OP]["AEF"+str(port)]+"raw_"
+        larchivepath=testarchivepath+project+"/"+portpathdict[OP][port]+"raw_"
     else:
-        larchivepath=archivepath+project+"/"+portpathdict[OP]["AEF"+str(port)]+"raw_"
+        larchivepath=archivepath+project+"/"+portpathdict[OP][port]+"raw_"
 #    NUC_parlog=AKF_1.read_restdb_old(archivepath+"PARLOG/V"+str(version)+"/_signal.json?from="+str(starttime)+"&upto="+str(stoptime))
     if version==0:
-        version=get_latest_version(portpathdict[OP]["AEF"+str(port)]+"raw_DATASTREAM",t_from=starttime)
+        version=get_latest_version(portpathdict[OP][port]+"raw_DATASTREAM",t_from=starttime)
     try:
         path_string = larchivepath+"PARLOG/V"+str(version)+"/_signal.json?from="+str(starttime)+"&upto="+str(int(starttime+1e9))
         res = urllib.request.urlopen(path_string)
@@ -2903,17 +2905,26 @@ def download_heatflux_by_times(port,tstart,tend,time_window=0,threads=1,testmode
                 if verbose>0:
                     print(now,"download_heatflux_by_times: heat flux data is not available")          
                 if request:
-                    f=open(heatflux_requestlist_path+str(now.year)+str(now.month+moffset)+"_q_requests.txt",'a')
                     try:
                         programid=AKF_2.get_program_id(tstart)
                     except Exception as E:
                         if verbose>0:
                             print('download_heatflux_by_times: Error! ',E)
-                        programid=str(tstart)
-                    f.write(programid+"\tAEF"+str(port)+"\n")
-                    f.close()
-                    if verbose>0:
-                        print("download_heatflux_by_times: heat flux calculation request logged for automatic processing (within ca. 1 day)")
+                        programid=str(tstart)                    
+                    cam_progs=IR_tools.get_work_list(heatflux_requestlist_path,typ='load')
+                    cam_progs_ig,reasons=IR_tools.get_work_list(heatflux_requestlist_path,typ='ignore')
+                    if (programid,"AEF"+str(port)) not in cam_progs and (programid,"AEF"+str(port)) not in cam_progs_ig:
+                        f=open(heatflux_requestlist_path+str(now.year)+str(now.month+moffset)+"_q_requests.txt",'a')                    
+                        f.write(programid+"\tAEF"+str(port)+"\n")
+                        f.close()
+                        if verbose>0:
+                            print("download_heatflux_by_times: heat flux calculation request logged for automatic processing (within ca. 1 day)")
+                    elif verbose>0:
+                        if (programid,'AEF'+str(port)) in cam_progs:
+                            print("download_heatflux_by_times: request exist already")
+                        else:
+                            pid=cam_progs_ig.index((programid,'AEF'+str(port)))
+                            print("download_heatflux_by_times: request ignored, data not available, reason: {0}".format(reasons[pid]))                    
             return exist,time,frames
 
 def download_heatflux_mapping_reference(timepoint=None,version=0,testmode=False,
@@ -3523,16 +3534,26 @@ def download_divertor_load(port,targetmodule=None,program=None,tstart=None,tend=
         if verbose>0:
             print(now,"download_divertor_load: divertor_load data is not available, creating request")          
         if request:
-            f=open(heatflux_requestlist_path+str(now.year)+str(now.month)+"_load_requests.txt",'a')
             try:
                 programid=AKF_2.get_program_id(tstart)
             except Exception as E:
                 if verbose>0:
                     print('download_divertor_load: Error! ',E)
                 programid=str(tstart)
-            f.write(programid+"\t"+str(port)+"\n")
-            f.close()
-
+            cam_progs=IR_tools.get_work_list(heatflux_requestlist_path,typ='load')
+            cam_progs_ig,reasons=IR_tools.get_work_list(heatflux_requestlist_path,typ='ignore')
+            if (programid,str(port)) not in cam_progs and (programid,str(port)) not in cam_progs_ig:
+                f=open(heatflux_requestlist_path+str(now.year)+str(now.month)+"_load_requests.txt",'a')            
+                f.write(programid+"\t"+str(port)+"\n")
+                f.close()
+                if verbose>0:
+                    print(now,"download_divertor_load: request created")
+            elif verbose>0:
+                if (programid,str(port)) in cam_progs:
+                    print(now,"download_divertor_load: request exist already")
+                else:
+                    pid=cam_progs_ig.index((programid,str(port)))
+                    print(now,"download_divertor_load: request ignored, data not availabel, reason: {0}".format(reasons[pid]))
     return exist,time,load,error
 
 def download_scene_model(port,program=None,timepoint=None,version=0,testmode=False,verbose=0):
@@ -3869,27 +3890,27 @@ def get_trigger_from_PID(program, port, testmode=False, verbose=0):
             print('get_trigger_from_PID: ERROR! number of segments does not indicate multiple shots.')
             
             return False, 0, 0, 0
-        
-    
+       
+   
 #%% dummy run of the script
     
 if __name__=='__main__':
     print("local function calling") 
     
 #%% temperature download and plotting example                  
-    port=31#"AEF50"#"AEF51"'20171114.053'#
-    prog="20180911.008"#"20181011.033"#'20171122.035'#'20181011.010'#'20180823.037'#'20170927.020'#"20181011.036"#"20181016.037"#"20180920.042"#"20171109.021"#"20181010.036"
-    status,time,images,valid=get_temp_from_raw_by_program(port,prog,time_window=[5,5.1],emi=0.80,T_version=2,version=0,threads=1,give_ERROR=False,use_firstframe_as_background=False,verbose=5)
+#    port=31#"AEF50"#"AEF51"'20171114.053'#
+#    prog="20180911.008"#"20181011.033"#'20171122.035'#'20181011.010'#'20180823.037'#'20170927.020'#"20181011.036"#"20181016.037"#"20180920.042"#"20171109.021"#"20181010.036"
+#    status,time,images,valid=get_temp_from_raw_by_program(port,prog,time_window=[5,5.1],emi=0.80,T_version=2,version=0,threads=1,give_ERROR=False,use_firstframe_as_background=False,verbose=5)
 #    status2,time2,images2=download_raw_images_by_program(port,prog,time_window=0.02,verbose=5)
 #    bla=get_calib_data(50,program=prog,verbose=5)
 #    success,t,s,profile=extract_temperature_profile_from_DL(port,np.asarray(time-time[0])/1e9,images,profile="TM3h_5_5",verbose=10,reference_time=time[0])
-    if status:
-        plt.figure()
-        plt.imshow(images[-1],vmin=330,vmax=1000,cmap=exJet)
-        cb=plt.colorbar()
-        cb.set_label("temperature in K",rotation=270,labelpad=20,fontsize=20)
-        cb.ax.tick_params(labelsize=20)
-        plt.title("AEF{0}".format(port))
+#    if status:
+#        plt.figure()
+#        plt.imshow(images[-1],vmin=330,vmax=1000,cmap=exJet)
+#        cb=plt.colorbar()
+#        cb.set_label("temperature in K",rotation=270,labelpad=20,fontsize=20)
+#        cb.ax.tick_params(labelsize=20)
+#        plt.title("AEF{0}".format(port))
 
 #%% heatflux test
 #    port = 20