function randomfly_from_dataset(ArenaID, gender_male, NF, datapath)
%
% Generate one virtural arena of random flies from dataset of real arenas
%
%** to generate a virtual arena with rand-females:  
%     gender_male  = 0;
%     ArenaID      = 1;                 % the #1 arena
%     NF           = 50;                % total number of flies
%     datapath     = 'E:\randomflies\'; % the path to save the virtual fly dish data
%     randomfly_from_dataset(ArenaID, gender_male, NF, datapath);
%
%** the arena and flies will be save to a file: 
%     savefilename = [datapath 'virtualdish-'  num2str(ArenaID) '-' gender_str]; 
%
%** to load the arena generated:
%     datapath     = 'E:\randomflies\';
%     ArenaID      = 1;  
%     gender_str   = 'rf' %random female. or 'rm' (random male)
%     load([datapath 'virtualdish-' num2str(ArenaID) '-' gender_str]);
% 
% YZ 2019

grfr_ver = '20190520';                       %ver: generate random fly from real

%load the dataset of real flies:
load(['E:\part of old 3G\' 'pathinfo.mat'], ...
     'dirlist', 'ind_rawD_result_crw', 'ind_rawD_n', ...  
     'ind_result_n', 'ind_xls_n', ...
     'ind_result_crw', 'ind_noresult_crw', 'ind_norawD_result', ...
     'cs_m_indx', 'cs_f_indx', 'singlesides'); 

if gender_male  % random male
    is_male    = 2;  
    gender_str = 'rm'; 
else            % random female
    is_male    = -1; 
    gender_str = 'rf';
end

ImgObjFilled   = zeros(2000, 2000);                                    % an area to simulate arena image
[cx0, cy0]     = deal(size(ImgObjFilled,2)/2, size(ImgObjFilled,1)/2); % the center for alignment
scale          = 0.075; 
RR             = [];
counter        = 0;

for rr_ii = 1:NF
    notdone    = 1;
    while notdone %this loop is to pick and check each fly, until find a good one
        counter         = counter + 1;
        %1. pick a random arena (main_ii list)
        if (gender_male == 0) % female 
            main_ii_set = [1:6 8:11 13:21 24:32 34:length(cs_f_indx)]; % actual female arenas
            pick_ii     = fix(rand(1)*length(main_ii_set))+1;
            main_ii     = main_ii_set(pick_ii);  
            ddii        = cs_f_indx(main_ii,1); % arenaID   
            ssii        = cs_f_indx(main_ii,2); % sideID
        else
            main_ii_set = [2:22 25:length(cs_m_indx)];                 % actual male arenas
            pick_ii     = fix(rand(1)*length(main_ii_set))+1;
            main_ii     = main_ii_set(pick_ii);
            ddii        = cs_m_indx(main_ii,1); % arenaID 
            ssii        = cs_m_indx(main_ii,2); % sideID
        end
        
        %2. pick a random frame (ffii): 
        ffii            = fix(rand(1)*5)+26; % frameID: between 26~30
        
        %3. load corresponding datafile:
        % load the actual arena
        dir_update_path = 'E:\part of old 3G'; 
        dir_update_pos  = 2; %replace part of path & name in direlist(xx) 
        [~, filename, bfileext] = fileparts(dirlist(ddii).name);
        datapath1       = [dir_update_path dirlist(ddii).path(dir_update_pos+1 : end) '\'];
        listresult      = dir([datapath1 '2*_infov2_' num2str(ssii), '.mat']);
        basename        = listresult(1).name(1:end-13);
        infofile        = [datapath1 listresult(1).name]; 
        Finfo           = load(infofile);   %load data of the arena (defined by ddii, ssii)

        %4. pick a random fly (fly_ii): 
        fly_ii          = fix(rand(1)*Finfo.step_c_info.fly(ffii).NF)+1; % flyID
        TF              = Finfo.step_c_info.fly(ffii).F(fly_ii);         % get the data of that fly
        
        %align circle center, and adjust scale
        scalefactor     = Finfo.circle_info.circles(ssii).scale/scale;
        the_x           = (TF.x+Finfo.circle_info.circles(ssii).roi.x0-Finfo.circle_info.circles(ssii).xc)*scalefactor+cx0;
        the_y           = (TF.y+Finfo.circle_info.circles(ssii).roi.y0-Finfo.circle_info.circles(ssii).yc)*scalefactor+cy0;
        
        if (the_x<=0) || (the_x>= size(ImgObjFilled,2)) continue; end % not in this region: skip and pick a new fly to try
        if (the_y<=0) || (the_y>= size(ImgObjFilled,1)) continue; end % same as above      

        [TF.x, TF.y]    = deal(the_x, the_y);
        TF.a            = TF.a*scalefactor;  
        TF.b            = TF.b*scalefactor; 
        
        %5. decide to keep or skip the new fly
        newflyimg = ellipseMatrix(TF.y, TF.x, TF.a, TF.b, TF.phi, zeros(size(ImgObjFilled)), 1); %generate an image of that fly in virtual arena
        if sum(sum(ImgObjFilled.*newflyimg)) %test the overlap -- if overlaps, skip and pick a new fly.
            continue; 
        else
            ImgObjFilled  = ImgObjFilled + newflyimg;      % image of arena filled with flies
            TF.realfly_id = [main_ii, ssii, ffii, fly_ii]; % keep info of the actual fly
            RF(rr_ii)     = TF;                            % info of the fly in the virtual arena 
            RR(rr_ii)     = Finfo.circle_info.circles(ssii).r*scalefactor; 
            notdone       = 0;
        end
    end % the while loop
end % the rr_ii loop

Radius = max(RR);

%optional: plot the image of the arena and flies
rr         = Radius; 
nps        = round(2*pi*rr);       % number of points
Theta      = linspace(0,2*pi,nps); % the angles
Rho        = ones(1,nps)*rr;       % polar coordinates
[CircleX,CircleY] = pol2cart(Theta,Rho);
CircleX    = CircleX+cx0; 
CircleY    = CircleY+cy0;
figure; image(ImgObjFilled*64); colormap(gray); hold on;
plot([RF(:).x],[RF(:).y],'r.'); 
for ii = 1:NF
    text([RF(ii).x]+5,[RF(ii).y]+5, num2str(ii), 'color', [0.5 0.5 0]); 
end
plot(cx0    ,cy0,      'r*');
plot(CircleX,CircleY, 'b--'); 


%decide on a ROI region enclosing the arena:
[roi.x0, roi.y0] = deal(floor(cx0-Radius), ceil(cy0-Radius));
[roi.w,   roi.h] = deal(   ceil(2*Radius), ceil(  2*Radius));
[roi.x1, roi.y1] = deal(     roi.x0+roi.w,     roi.y0+roi.h);
for ii= 1:NF  % correcting for roi:
    RF(ii).x = RF(ii).x - roi.x0 + 1;
    RF(ii).y = RF(ii).y - roi.y0 + 1;
end

%force these onto new flies before save the data
ssii        = 1;  
ffii        = 30;
this_id     = ArenaID; %each virtual dish has a unique id

time_now    = now;
timestr     = datestr(time_now,'yyyymmddHHMM');
timestrlong = datestr(time_now,'yyyymmdd_HHMMSS');

blankimg    = zeros(size(ImgObjFilled), 'uint8');   
Radius2     = Radius^2;
[Xpt, Ypt]  = meshgrid(1:size(blankimg,2), 1:size(blankimg,1));
MaskL       = uint8(((Xpt-cx0).^2 + (Ypt-cy0).^2) <= Radius2);
MaskIC      = MaskL;
MaskICEX    = uint8(bwmorph(MaskIC,'thicken',30) - bwmorph(MaskIC,'thicken',25));                 
MaskIC_prop = regionprops(MaskIC,'MajorAxisLength', 'MinorAxisLength', 'Centroid', 'ConvexHull'); 
bg1         = blankimg(roi.y0:roi.y1,roi.x0:roi.x1);     
img1        = ImgObjFilled(roi.y0:roi.y1,roi.x0:roi.x1);

circles(ssii) = struct(    ...
          'xc',  cx0,      ...
          'yc',  cy0,      ...
           'r',  Radius,   ...
         'roi',  roi,      ... 
          'xs',  CircleX,  ...
          'ys',  CircleY,  ...
       'scale',  scale);

%fill into data structures as the real flies (all are necessary):
para.ver         = grfr_ver;
para.gender_l    = gender_str;
para.genotype_l  = gender_str; %same
para.diameter_l  = 90; %mm 
para.flynumber_l = NF;
para.scale       = scale;

circle_info = struct(         ...
         'env',  [],          ... 
         'ver',  datestr(now,'yyyymmddHHMM'),    ...
        'time',  datestr(now,'yyyymmddHHMM'),    ...
    'basename',  datestr(now,'yyyymmdd_HHMMSS'), ...
        'ddii',  0,           ... 
     'main_ii',  this_id,     ... 
     'is_male',  is_male ,    ...
    'data_opt',  [1 0 1 1 0], ... 
    'para_opt',  2,           ... 
     'run_opt',  1,           ... 
    'screen_p',  [],          ... 
     'bkgd_fm',  [],          ... 
        'bkgd',  blankimg,    ... 
     'alldish',  blankimg + 255, ... 
        'para',  para,        ...
          'PP',  [],          ... 
     'circles',  circles,     ... 
       'MaskL',  MaskL,       ... 
       'MaskR',  blankimg,    ... 
     'MaskAll',  MaskL,       ...
         'IMG',  ImgObjFilled,...
      'IMGroi',  img1);       
  
step_a_info = struct(        ...
         'env',  [],         ... 
         'ver',  grfr_ver,   ...
        'time',  timestr,    ...
        'ddii',  0 ,         ...
        'ssii',  1 ,         ...
     'main_ii',  this_id ,   ...
     'is_male',  is_male ,   ...
    'basename',  timestrlong,...
    'imageseq',  [8:30],     ...
   'filelabel',  '201905',   ...
      'THDS_V',  [75 85 90 95], ...
     'MORETHD',  30,         ...
     'MINAREA',  180,        ...
   'MINDSOLID',  0.3,        ...
'MINAXISRATIO',  0.2,        ...
      'MaskIC',  MaskIC ,    ...
    'MaskICEX',  MaskICEX,   ...
 'MaskIC_prop',  MaskIC_prop,...
   'divframes',  zeros(1,30),...
       'BGroi',  bg1,        ...
   'DrivePath',  datapath,   ...
    'datapath',  datapath,   ...
     'objstat',  [],         ...
     'logfile',  '');  
    
step_b_info = struct(        ...
           'env',  [],       ... 
           'ver',  grfr_ver, ...
          'time',  timestr,  ...
      'divlines',  [],       ...
'ENLARGE_FACTOR',  2 ,       ...
  'ENLARGE_EDGE',  10,       ...
   'PEELING_MAX',  12);  

clear fly       
fly(ffii).F  = RF;
fly(ffii).NF = NF;
step_c_info = struct(        ...
              'env',  [],    ... 
              'ver',  grfr_ver,  ...
             'time',  timestr,   ...
              'fly',  fly,   ...
         'TotalObj',  [],    ...
     'GoodObj_indx',  [],    ...  
      'BadObj_indx',  [],    ...  
          'objstat',  [],    ...
    'Min_Intensity',  [],    ...
           'time_3',  [],    ...
     'newarea_stdx',  0);     

%save the data to a file
savefilename = [datapath 'virtualdish-'  num2str(this_id) '-' gender_str]; 
save(savefilename,    ...
    'circle_info',    ...
           'ssii',    ...
    'step_a_info',    ...
    'step_b_info',    ...
    'step_c_info',    ...
    'counter', 'NF', 'gender_male'); 

fprintf('%d out of %d trails. ', NF, counter);    
fprintf('Data of random fly saved to: %s.\n', savefilename);




