#!/usr/bin/perl
# modish, version 0.26 (written in April 2015. Last debug 1 January 2016. Last text check 9.10.2016)

# Summary. 
# This is modish.pl, an xperimental program for Building Performance Simulation software. 
# modish.pl brings into account the reflective effect of solar obstructions on solar gains 
# in ESP-r building models on the basis of irradiance ratios. Those ratios are obtained 
# combining the direct radiation on a surface and the total radiation calculated by the means 
# of a raytracer (Radiance) on the same surface.

# More detailed presentation. 
# modish.pl is a program for calculating modifications of the diffuse solar shading
# factors in the ISH (shading and insolation) files of the ESP-r building performance 
# simulation suite (http://www.esru.strath.ac.uk/Programs/ESP-r.htm) by taking
# into accont the irradiance rations calculated by the means of
# the Radiance lighting simulation suite (http://radsite.lbl.gov/radiance/).
# The aim of the procedure is to take into account the effect of reflections due to solar obstructions. 
# 
# How the program works.
# The effect of solar reflections is taken into account at each hour on the basis of the ratios 
# between the irradiances measured at the models' surfaces in: a) the original model;   
# b) a transitional model derived from that.
# The irradiances are calculated through Radiance and derive from the following building models:
# a) a model in which the solar obstructions have their true reflectivity 
# and all the other surfaces (with the exception of the ground) are completely black;
# b) a model in which the solar obstructions and all the other surfaces (with the exception 
# of the ground) are completely black.
# The value given by 1 minus those irradiance ratios gives the diffuse shading factors that are 
# put in the ISH file in place of the original values.
# The original ISH's ".shda" files are not substituted. Two new files are added in the "zone" 
# folder of the ESP-r model: 
# the ".mod.shda" file is usable by ESP-r. It features the newly calculated shading factors;
# the ".report.shda" file lists the original shading factors and, at the bottom, the irradiance 
# ratios from which the new shading factors in the ".mod.shda" 
# file have been derived. Note that when the radiation on a surface is increased, instead of 
# decreased, as an effect of reflections on obstructions, the shading factor will be negative.
# "modish.pl" has to be launched through the shell with a command like this:
# < perl  modish.pl   path_to_the_ESP-r_model_configuration_file   zone_number  surface_number_1   surface_number_2  ...  surface_number_n >
# An example of launch line may be: < perl modish.pl /home/luca/boxform/cfg/boxform.cfg 1 1 7 >.
# The path of the ESP-r model configuration path has to be specified in full, like in the example above.
# In calculating the irradiance ratios, the program defaults to: diffuse reflections: 1 ; 
# direct reflections: 7; surface grid: 2 x 2; direction vectors for each surface: 1 ;
# distance from the surface for calculating the irradiances: 0.01 (metres); ratio of the of the original
# shading factor to the "new" shading factor under which the new shading factor is used to substitute 
# the original one in the ".shda" file. If this value is 1, it is inactive, there is no threshold.
# These defaults are a compromise between quality and speed. They can be overridden by preparing 
# a "modish_defaults.pl" file and placing it in the same directory of "modish.pl".
# The content of a configuration file for the present defaults, for example,
# would be constituted by the following line (note that after it a line of comment follows):
# @defaults = ( [  2, 2 ], 1, 1, 7, 0.01, 1 );
### ( [ resolution_x, resolution_y ], $dirvectorsnum, $bounceambnum, $bouncemaxnum, $distgrid, $threshold )
# The value "$dirvectorsnum" controls the numbers of direction vectors that are used for 
# computing the irradiances at each point of each grid over the surfaces. The values that currently
#  can be chosen are 1, 5 and 9. When the points are more than 1, they are evenly distributed 
# on a hemisphere following a precalculated geodetic pattern.
# modish.pl works with no limitation of number of surfaces, it can be used with complex geometries
# and takes into account parent and child surfaces.
# For the program to work correctly, the materials, construction and optics databases
# must be local to the ESP-r model.
# A number of Perl modules has to be installed as a prerequisite to run "modish.pl".
# They are: Math::Trig; List::Util; List::MoreUtils; List::AllUtils; Data::Dump; 
# Data::Dumper; Vector::Object3D::Polygon; Math::Polygon::Tree .
# "modish.pl" must be presently accompanied by the programs "fix.sh" and "perlfix.pl", which must reside
# in its same directory. 
# Ihe ESP-r "e2rfile.F" source file checked before compilation to verify that
# it calls these programs just after the Radiance materials file (".mat") has been created, 
# i.e. just before the line "C Inside description file." 
# (line 587 of ESP-r release 12.4) in the file "e2rfile.F" .
# If the following Fortran line is absent, it has to be added:  system('./fix.sh')  .
# To install Perl modules from the Comprehensive Perl Archive Network (CPAN), 
# it is advisable that the Perl program "cpanminus" is used. To install Math::Trig, for example, 
# the following command should be given to the shell as a superuser: 
# < cpanm Math::Polygon::Tree >.
# Author: Gian Luca Brunetti, Politecnico di Milano - gianluca.brunetti@polimi.it.
# All rights reserved, 2015-16.
# This is free software.  You can redistribute it and/or modify it under the terms of the 
# GNU General Public License, version 2 or newer, as published by the Free Software Foundation.


use v5.14;
use Exporter;
use parent 'Exporter';
use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS );
use Math::Trig;
use List::Util qw[ min max reduce shuffle];
use List::MoreUtils qw(uniq);
use List::AllUtils qw(sum);
#use File::Monitor::Lite;
#use File::Monitor::Simple;
#use File::Modified;
use Data::Dump qw(dump);
use Data::Dumper;
$Data::Dumper::Terse  = 1;
$Data::Dumper::Purity  = 1;
use Vector::Object3D::Polygon;
use Math::Polygon::Tree;
use feature 'say';    
no strict; 
no warnings;
our @ISA = qw(Exporter);
@EXPORT = qw( modish );
$ABSTRACT = 'This is modish.pl, a program for calculating the modification of diffuse solar shading in the ISH (shading and insolation) files of the ESP-r building performance simulation suite.';

#########################################################################################

if ( ( "$^O" eq "MSWin32" ) or ( "$^O" eq "MSWin64" ) )
{ 
  say "\nSorry, this function presently works only on Linux and OSX." and die;
}

my ( @zoneshds, @winsdata );
my ( %surfslist, %shdfileslist, %obsinfo );

my %days_inmonths = ( Jan => 15, Feb => 14, Mar => 15, Apr => 15, May => 15, Jun => 15, Jul => 15, Aug => 15, Sep => 15, Oct => 15, Nov => 15, Dec => 15 );
my %monthsnum = ( Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12 );

sub getmonthname
{
  my $monthnum = shift;
  
  my %monthsnames = ( 1 => "Jan" , 2 => "Feb", 3 => "Mar", 4 => "Apr", 5 => "May", 6 => "Jun", 7 => "Jul", 8 => "Aug", 9 => "Sep", 10 => "Oct", 11 => "Nov", 12 => "Dec" );
  my $monthname = $monthsnames{ "$monthnum" };
  return $monthname;
}

sub getmonthnum
{
  my $monthname = shift;
  my %monthsnums = ( Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12 );
  my $monthnum = $monthsnums{ "$monthname" };
  return $monthnum;
}

sub _mean_ { return @_ ? sum(@_) / @_ : 0 }

sub getconffilenames
{  # THIS GETS THE CONSTRUCTION AND MATERIALS FILES FROM THE CFG FILE. IT IS CALLED BY sub createfictitious
  my ($conffile, $path, $askedzonenum ) = @_; #say REPORT "\$conffile: " . dump($conffile); say REPORT "\$path: " . dump($path); say REPORT "\$askedzonenum: " . dump($askedzonenum);
  open (CONFFILE, "$conffile") or die;
  my @lines = <CONFFILE>;
 # say REPORT "READ @lines!";
  close CONFFILE;
  my ($constrdbfile, $matdbfile);
  my @zonedata;
  my $semaphore;
  my $countline = 0;
  my $countzone = 0;
  foreach my $line (@lines)
  {
    my ($geofile, $constrfile, $shdfile, $zonenum_cfg );
    #my $readline = $line;
    $readline = s/^\s+//;
    my @row = split(/\s+|,/, $line); 
    if ($row[0] eq "*mlc")
    {
      $constrdbfile = $row[1];
      $constrdbfile =~ s/\.\.//;  
      $constrdbfile = $path . $constrdbfile; #say REPORT "\$constrdbfile " . dump($constrdbfile);
    }
    elsif ($row[0] eq "*mat")
    {
      $matdbfile = $row[1]; 
      $matdbfile =~ s/\.\.//;  
      $matdbfile = $path . $matdbfile; #say REPORT "\$matdbfile " . dump($matdbfile);
    }
    elsif ($row[0] eq "*zon")
    {
      $countzone++; 
      my $zonenum = $row[1]; #say REPORT "\$zonenum " . dump($zonenum);
      if ( $zonenum eq $askedzonenum )
      {
        $semaphore = "yes";
        push ( @{$zonedata[$countzone -1]}, $zonenum );
      }
      else
      {
        $semaphore = "no";
      }
    }
    
    if ( ($row[0] eq "*geo") and ( $semaphore eq "yes" ) )
    {
      $geofile = $row[1]; 
      $geofile =~ s/\.\.//; 
      $geofile = $path . $geofile; say REPORT "\$geofile " . dump($geofile);
      push ( @{$zonedata[ $countzone -1 ]}, $geofile );
    }
    elsif ( ($row[0] eq "*con") and ( $semaphore eq "yes" ) )
    {
      $constrfile = $row[1];
      $constrfile =~ s/\.\.//; 
      $constrfile = $path . $constrfile; #say REPORT "\$constrfile " . dump($constrfile);
      push ( @{$zonedata[ $countzone - 1 ]}, $constrfile );

    }
    elsif ( ( $row[0] eq "*isi") and ( $semaphore eq "yes" ) )
    {
      $shdfile = $row[1]; 
      $shdfile =~ s/\.\.//; 
      $shdfile = $path . $shdfile;  #say REPORT "\$shdfile " . dump($shdfile);
      push ( @{$zonedata[ $countzone - 1 ]}, $shdfile );
    }
  } #say REPORT "ZONEDATA! " . dump(@zonedata);
  #say REPORT "CONSTRDBFILE: " . $constrdbfile . ", MATDBFILE: " . $matdbfile . ", ZONEDATA: " . dump( @zonedata );
  return ( $constrdbfile, $matdbfile, \@zonedata, \@lines );
}

sub createfictitiousfiles
{
  #THIS CREATE FILES FOR THE MODELS FEATURING FICTITIOUS QUALITIES AIMED TO THE MAIN modish PROGRAM AND MODIFIES MATERIALS DB AS REQUESTED
  # _AND_ PREPARES THE CONFIGURATION FILES FOR THE FICTITIOUS MODELS ACCORDINGLY
  my ($conffile, $path, $zonenum) = @_; #say REPORT "\$conffile: " . dump($conffile); say  REPORT "\$path " . dump($path); say  REPORT "\$zonenum " . dump($zonenum);
  my $conffile_fict1 = $conffile;
  my ($flaggeo, $flagconstrdb, $flagmatdb, $flagconstr);
  $conffile_fict1 =~ s/\.cfg/\_fict1\.cfg/; #say REPORT "\$conffile_fict1: " . dump($conffile_fict1);
  my $conffile_fict2 = $conffile;
  $conffile_fict2 =~ s/\.cfg/\_fict2\.cfg/; #say REPORT "\$conffile_fict2: " . dump($conffile_fict2);
  my $conffile_fict3 = $conffile;
  $conffile_fict3 =~ s/\.cfg/\_fict3\.cfg/; #say REPORT "\$conffile_fict3: " . dump($conffile_fict3);
  `cp -R -f $conffile $conffile_fict1\n`; 
  `cp -R -f $conffile $conffile_fict2\n`;
  `cp -R -f $conffile $conffile_fict3\n`;
    
  my ($constrdbfile, $matdbfile, $zonedataref, $conflinesref) = getconffilenames($conffile, $path, $zonenum); 
  my @zonedata = @$zonedataref; #say REPORT "ZONEDATA: " . dump(@zonedata);
  my @conflines = @$conflinesref; #say REPORT "\@conflines: " . dump(@conflines);
  my (@originals, @fictitia1, @fictitia2, @fictitia3 ); 
  
  push ( @originals, $constrdbfile);
  
  my $constrdbfile_fict = $constrdbfile; 
  $constrdbfile_fict = $constrdbfile . "_fict" ;  
  push ( @fictitia1, $constrdbfile_fict);
  push ( @fictitia2, $constrdbfile_fict);
  push ( @fictitia3, $constrdbfile_fict);
  
  push ( @originals, $matdbfile);
  
  my $matdbfile_fict1 = $matdbfile; #say REPORT "\$matdbfile_fict1: " . dump($matdbfile_fict1);
  $matdbfile_fict1 = $matdbfile . "_fict1";  
  push ( @fictitia1, $matdbfile_fict1 );
  
  my $matdbfile_fict2 = $matdbfile; 
  $matdbfile_fict2 = $matdbfile . "_fict2"; #say REPORT "\$matdbfile_fict2: " . dump($matdbfile_fict2);
  push ( @fictitia2, $matdbfile_fict2 );
  
  push ( @fictitia3, $matdbfile_fict1 );
  
  
  foreach my $datum (@zonedata)
  {
    my ( @tempbox_original, @tempbox_fictitia1, @tempbox_fictitia2, @tempbox_fictitia3 );
    my @array = @$datum;  #say REPORT "\@array\: " . dump(@array);
    #if ( $zonenum == $zonenum )
    {
      my $geofile = $array[1];
      push ( @tempbox_originals, $geofile );
      
      my $geofile_fict = $geofile; 
      $geofile_fict =~ s/\.geo/_fict\.geo/;  #say REPORT "\$geofile_fict: " . dump($geofile_fict);
      
      my $geofile_fict3 = $geofile;
      $geofile_fict3 =~ s/\.geo/_fict3\.geo/;

      push ( @tempbox_fictitia1, $geofile_fict);
      push ( @tempbox_fictitia2, $geofile_fict);
      push ( @tempbox_fictitia3, $geofile_fict3);
      
      my $constrfile = $array[2];
      push ( @tempbox_originals, $constrfile);
      
      my $constrfile_fict1 = $constrfile; 
      $constrfile_fict1 =~ s/\.con/_fict1\.con/;  #say REPORT "\$constrfile_fict1: " . dump($constrfile_fict1);
      push ( @tempbox_fictitia1, $constrfile_fict1);
      
      my $constrfile_fict2 = $constrfile; 
      $constrfile_fict2 =~ s/\.con/_fict2\.con/;  #say REPORT "\$constrfile_fict2: " . dump($constrfile_fict2);
      push ( @tempbox_fictitia2, $constrfile_fict2);
      
      push ( @tempbox_fictitia3, $constrfile_fict1);
            
      #unless (-e $constrfile_fict1) { 
	`cp -R -f $constrfile $constrfile_fict1\n`; $flagconstr = "y"; 
      #} 
      #unless ( -e $constrfile_fict2 ) { 
        `cp -R -f $constrfile $constrfile_fict2\n`; $flagconstr = "y"; 
      #}
      
      my $shdfile = $array[3]; 
      push ( @tempbox_originals, $shdfile);
      push ( @tempbox_fictitia1, $shdfile);
      push ( @tempbox_fictitia2, $shdfile);
      push ( @tempbox_fictitia3, $shdfile);
      
      my $zonenum_cfg = $array[0];
      push ( @tempbox_originals, $zonenum_cfg);
      push ( @tempbox_fictitia1, $zonenum_cfg);
      push ( @tempbox_fictitia2, $zonenum_cfg);
      push ( @tempbox_fictitia3, $zonenum_cfg);
      
      push ( @originals, [ @tempbox_originals ] );
      push ( @fictitia1, [ @tempbox_fictitia1 ] );
      push ( @fictitia2, [ @tempbox_fictitia2 ] );
      push ( @fictitia3, [ @tempbox_fictitia3 ] );
    }  
  }
  
  my ( @correctlines, $addline );
  open (CONFFILE_FICT1, ">$conffile_fict1");  
  my @conflines2 = @conflines;
  
  foreach my $line (@conflines)
  {
    my $counter = 0;
    foreach my $elt ( @fictitia1 )
    {
      if ( not ( ref($elt) ) )
      {
        my $original = $originals[$counter]; #say REPORT "ORIGINAL: $original, ELT: " . dump( $elt );
        $elt =~ s/$path//; #say REPORT "\$elt: $elt, ELT: " . dump( $elt );
        $original =~ s/$path//; #say REPORT "\$path: $path, ELT: " . dump( $elt );
        if ( $elt )
        {
          $line =~ s/$original/$elt/; #say REPORT "\$line: $line, ELT: " . dump( $elt );
        }
      }
      else
      {
        my @elts = @$elt;
        my @originalelts = @{$originals[$counter]}; 
        my $count = 0;
        foreach my $el ( @elts )
        {
          my $original = $originalelts[$count]; #say REPORT "ORIGINAL: $original, ELT: " . dump( $elt );
          $el =~ s/$path//; #say REPORT "\$elt: $elt, ELT: " . dump( $elt );
          $original =~ s/$path//; #say REPORT "\$path: $path, ELT: " . dump( $elt );
          if ( $el )
          {
            $line =~ s/$original/$el/; #say REPORT "\$line: $line, ELT: " . dump( $elt );
          }
          $count++;
        }
      }
      
      if ( ( $counter == 0 ) and ( not ( $line =~ /^\*/ ) ) )
      {
        open( CORRECTCONF, $conffile ) or die;
        @correctlines = <CORRECTCONF>;
        close CORRECTCONF;
      }
      if ( @correctlines )
      {
        $addline = /^(.)$correctlines[ $counter ]/;
        if ( $addline )
        {
          $line = $addline . $line;
        }
      }
      $counter++;
    }
    
    print CONFFILE_FICT1 $line; #say REPORT "\$line: $line, ELT: " . dump( $elt );
  }
  close CONFFILE_FICT1;
  
  open (CONFFILE_FICT2, ">$conffile_fict2");
  foreach my $line (@conflines2)
  {
    my $counter = 0;
    foreach my $elt ( @fictitia2 )
    {
      if ( not ( ref($elt) ) )
      {
        my $original = $originals[$counter]; #say REPORT "ORIGINAL: $original, ELT: " . dump( $elt );
        $elt =~ s/$path//; #say REPORT "\$elt: $elt, ELT: " . dump( $elt );
        $original =~ s/$path//; #say REPORT "\$path: $path, ELT: " . dump( $elt );
        if ( $elt )
        {
          $line =~ s/$original/$elt/; #say REPORT "\$line: $line, ELT: " . dump( $elt );
        }
      }
      else
      {
        my @elts = @$elt;
        my @originalelts = @{$originals[$counter]}; #say REPORT "ORIGINAL: $original, ELT: " . dump( $elt );
        my $count = 0;
        foreach my $el ( @elts )
        {
          my $original = $originalelts[$count]; #say REPORT "ORIGINAL: $original, ELT: " . dump( $elt );
          $el =~ s/$path//; #say REPORT "\$el: $el, ELT: " . dump( $elt );
          $original =~ s/$path//; #say REPORT "ORIGINAL: $original, ELT: " . dump( $elt );
          if ( $el )
          {
            $line =~ s/$original/$el/; #say REPORT "\$line: $line, ELT: " . dump( $elt );
          }
          $count++;
        }
      } 
      if ( @correctlines )
      {
        $addline = /^(.)$correctlines[ $counter ]/;
        if ( $addline )
        {
          $line = $addline . $line;
        }
      }      
      $counter++;
    }
    print CONFFILE_FICT2 $line;
  }
  close CONFFILE_FICT2;
  
  open (CONFFILE_FICT1, "$conffile_fict1");
  my @conflines3 = <CONFFILE_FICT1>;
  close CONFFILE_FICT1;
  
  open (CONFFILE_FICT3, ">$conffile_fict3");
  my $count = 0;
  foreach my $line (@conflines3)
  {
    my $redflag;
    if ( $$conflines3[ $count + 1] =~ /^# block entities:/ )
    {
      $redflag = "yes";
    }
    if ( @correctlines )
    {
      $addline = /^(.)$correctlines[ $count ]/;
      if ( $addline )
      {
        $line = $addline . $line;
      }
    }
    unless ( $redflag eq "yes" )
    {
      unless ( $line =~ /^\*shad_calc,/ )
      {
        print CONFFILE_FICT3 $line;
      }
      else
      {
        print CONFFILE_FICT3 "*shad_calc,none  # no temporal shading requested\n";
      }
    }
    $count++;
  }
  close CONFFILE_FICT3;
  
  setroot( $conffile_fict1, $path );
  setroot( $conffile_fict2, $path );
  
  return ($conffile, $conffile_fict1, $conffile_fict2, $conffile_fict3, $constrdbfile, $constrdbfile_fict,
  $matdbfile, $matdbfile_fict1, $matdbfile_fict2, $flagconstrdb, $flagmatdb, $flaggeo, $flagconstr, [ @originals ], [ @fictitia1], [ @fictitia2 ] , [ @fictitia3 ] );
}

sub definepath
{
  # THIS DEFINES THE PATH STARTING FROM THE CONFIGURATION FILE PATH. IT IS CALLED FROM sub modish
  my $path = shift;
  $path =~ s/\/cfg(.+)$//;
  return ($path);
}

sub readgeofile
{  # THIS READS A GEO FILE TO GET THE DATA OF THE REQUESTED SURFACES
  my $geofile = $_[0]; 
  my @transpsurfs = @{$_[1]}; #say REPORT "transpsurfs: " . dump(@transpsurfs);
  my $zonenum = $_[2]; #say REPORT "$zonenum $zonenum";
  open (GEOFILE, "$geofile") or die;
  my @lines = <GEOFILE>;
  close GEOFILE;
  my ( @geofilestruct, @transpelts, @obs );
  my %datalist;
  my $countsurf = 0;
  foreach my $surfnum ( @transpsurfs )
  {
    foreach my $line (@lines)
    {
      my @elts = split(/\s+|,/, $line); #say REPORT "elts: " . dump(@elts);
      if ( $elts[0] eq "\*surf")
      {
        my $surfname = $elts[1]; 
        my $surfnum = $elts[12]; 
        my $parent = $elts[3]; #say REPORT "HERE \$parent " . dump($parent);
        my $constr = $elts[6]; 
        # THIS POPULATES THE VARIABLE %surfslist (HASH - DICTIONARY - ASSOCIATIVE ARRAY) LINKING ZONES, SURFACES NAMES AND SURFACE NUMBER:

        $surfslist{ $zonenum }{ $surfnum }{surfname} = $surfname;
        $surfslist{ $zonenum }{ $surfname }{surfnum} = $surfnum;
        $datalist{ $zonenum }{ $surfnum }{ surfname } = $surfname;
        $datalist{ $zonenum }{ $surfnum }{ parent } = $parent;
        $datalist{ $zonenum }{ $surfnum }{ constr } = $constr;
        $datalist{ $zonenum }{ $surfnum }{ surfnum } = $surfnum;  
        $datalist{ $zonenum }{ $surfnum }{ geofile } = $geofile;
        unless ( $parent eq "-" ) 
        { 
          my $parentnum = $surfslist{ $zonenum }{ $parent }{surfnum}; #say REPORT "HERE FOCUS \$parentnum " . dump($parentnum);
          push ( @{ $datalist{ $zonenum }{ children }{ $parentnum } }, $surfnum ); #say REPORT "HERE FOCUS \$datalist " . dump($datalist);
          @{ $datalist{ $zonenum }{ children }{ $parentnum } } = uniq( @{ $datalist{ $zonenum }{ children }{ $parentnum } } );
        }
        
      }
      
      if ( $elts[0] eq "\*vertex")
      {
        my $x =  $elts[1];
        my $y =  $elts[2];
        my $z =  $elts[3];
        my $vertnum =  $elts[5];
        $datalist{ $zonenum }{ vertex }{ $vertnum } = [ $x, $y, $z ];
      }
      
      if ( $elts[0] eq "\*edges")
      {
        my $surfnum = $elts[ $#surfnum ]; 
        my $border = scalar( @elts - 3 );
        my @vertnums = @elts[ 1..$border ]; #say REPORT "\@vertnums " . dump(@vertnums);
        $datalist{ $zonenum }{ $surfnum }{ edges }{ $surfnum } = [ @vertnums ]; 
      }
      
      if ( ($elts[0] eq "\*surf") and ( $surfnum == $elts[12] ) )
      {
        my $surfname = $elts[1]; #say REPORT "surfname " . dump($surfname);
        my $parent = $elts[3]; #say REPORT "\$parent " . dump($parent);
        my $constr = $elts[6]; #say REPORT "\$constr " . dump($constr);
        my $surfnum = $elts[12]; #say REPORT "\$surfnum " . dump($surfnum);
        push (@transpelts, [ $surfname, $parent, $constr, $surfnum, $geofile, $zonenum ] ); 
      } #say REPORT "\@transpelts " . dump(@transpelts);
      
      if ($elts[0] eq "\*obs")
      {
        my $obsconstr = $elts[10]; #say REPORT "\$obsconstr " . dump($obsconstr);
        my $obsname = $elts[9]; #say REPORT "\$obsname " . dump($obsname);
        my $obsnum = $elts[13];  #say REPORT "\$obsnum " . dump($obsnum);
        push (@obs, [ $obsname, $obsconstr, $obsnum ] ); 
      } #say REPORT "\@obs " . dump(@obs);
      if ( $countsurf == 0 )
      {
        push ( @geofilestruct, [ @elts ] );
      }
    }
    $countsurf++;
  }
  
  foreach ( @geofilestruct )
  {
    my $obsmaterial = $_->[10];
    my $obsnumber = $_->[13];
    if ( ( $_->[0] eq "#" ) and ( $_->[1] eq "*obs" ) )
    {
      $semaphore = 1;
    }
    if ( ( $semaphore == 1) and ( $_->[0] eq "*obs" ) )
    {
      push ( @obsconstr,$obsmaterial = $_->[10] );
    }
    $obsinfo{ $obsnumber } = $obsnumber;
    $obsinfo{ $obsmaterial } = $obsmaterial;
  }
  my @obsconstrset = uniq( @obsconstr );
    
  return ( \@transpelts, \@geofilestruct, \%surfslist, \@obs, \@obsconstrset, \%datalist );
}

sub readverts
{
  # THIS READS THE VERTEX NUMBERS OF THE REQUESTED SURFACES IN A GEO FILE
  my @transpelts = @{$_[0]}; #say REPORT "\@transpelts " . dump(@transpelts);
  my $geofile = $_[1]; #say REPORT "\$geofile " . dump($geofile);
  my @geodata = @{$_[2]}; #say REPORT "\@geodata " . dump(@geodata);
  my %datalist = %{$_[3]}; #say REPORT "\%datalist " . dump(%datalist);
  my @winselts;
  foreach my $transpelt (@transpelts)
  {  #say REPORT "\$transpelt " . dump($transpelt);
    my $surfname = $transpelt->[0]; #say REPORT "\$surfname " . dump($surfname);
    my $parent = $transpelt->[1]; #say REPORT "\$parent " . dump($parent);
    my $constr = $transpelt->[2]; #say REPORT "\$constr " . dump($constr);
    my $surfnum = $transpelt->[3]; #say REPORT "\$surfnum " . dump($surfnum);
    my $geofile = $transpelt->[4]; #say REPORT "\$geofile " . dump($geofile);
    my $zonenum = $transpelt->[5]; #say REPORT "\$zonenum " . dump($zonenum);
    my @winelts;
    foreach my $datum (@geodata)
    {
      my @data = @$datum;  #say REPORT "\@data " . dump(@data);
      if ( ($data[0] eq "*edges") and ( $data[$#data] == $surfnum ) )
      {
        push ( @winelts, [ [ @data[ 2..( $#data - 2 ) ] ], $surfnum ] ); 
        my @surfverts = @data[ 2..( $#data - 2 ) ]; #say REPORT "\@surfverts ". dump(@surfverts);
        $datalist{ $zonenum }{ $surfnum }{vertnums} = [ @surfverts ];
      }
    } #say REPORT "\@winelts ". dump(@winelts);
    push ( @winselts, [ @winelts ] );
  }
  return ( \@winselts, \%datalist );
}


sub readcoords
{
  # THIS READS THE COORDINATES OF THE REQUESTED VERTEX NUMBERS
  my ( $winseltsref, $geofile, $geodataref, $datalistref, $transpeltsref ) = @_; #say REPORT "\$geofile " . dump($geofile);
  my @winselts = @$winseltsref; #say REPORT "IN READCOORDS winselts: " . dump(@winselts);
  my @geodata = @$geodataref; #say REPORT "IN READCOORDS \@geodata " . dump(@geodata);
  my %datalist = %$datalistref; #say REPORT "IN READCOORDS \%datalist " . dump(%datalist);
  my @transpelts = @$transpeltsref; #say REPORT "IN READCOORDS \@transpelts " . dump(@transpelts);
  my @allcoords;
  my $count = 1;
  foreach my $winseltref (@winselts)
  {
    my @transpelt = @{ $transpelts[ $count -1 ] }; #say REPORT "SAYHERE \@transpelt ". dump(@transpelt);
    my $zonenum = $transpelt[5];  #say REPORT "SAYHERE \$zonenum ". dump($zonenum);

    my @winselt = @$winseltref;
    my @vertnums = @{ $winselt[0][0] }; #say REPORT "SAY \@vertnums " . dump(@vertnums);
    my $surfnum = $winselt[0][1]; #say REPORT "SAY \$surfnum " . dump($surfnum);
    my @coords;
    foreach my $num (@vertnums)
    {
      
      foreach my $datum (@geodata)
      {
        my @data = @$datum;
        if ( ($data[0] eq "*vertex") and ( $data[5] == $num ) )
        {
          push ( @coords, [ [ @data[ 1..3 ] ], $num ] ); #say REPORT "\@allcoords: " . dump(@allcoords);
          $datalist{ $zonenum }{ $num }{vertcoords} = [ @data[ 1..3 ] ];
        }
      }
    }
    push ( @allcoords, [ @coords ] ); 
    $count++;
  }
  return (\@allcoords, \%datalist );
}

sub getcorners
{
  # THIS PACKS INTO SUBARRAYS THE X, Y, AND Z COORDINATES OF THE vertices OF THE REQUESTED SURFACES
  my ( $winscoordsref, $winseltsref ) = @_;
  my @winscoords = @$winscoordsref; 
  my @winselts = @$winseltsref; 
  my @packsurfsdata;
  my $countsurf = 0;
  foreach $surfcoordsref ( @winscoords )
  {
    my @surfcoords = @$surfcoordsref; 
    my ( @xdata, @ydata, @zdata );
    my @packsurfdata;
    my $surfnum = $winselts[$countsurf][0][1]; 
    foreach my $coordsetref (@surfcoords)
    {
      my @coordset = @$coordsetref; 
      push (@xdata, $coordset[0][0]);
      push (@ydata, $coordset[0][1]);
      push (@zdata, $coordset[0][2]);
    }
    push (@packsurfdata, [ @xdata ], [ @ydata ], [ @zdata ], $surfnum  );
    push ( @packsurfsdata, [ @packsurfdata ] ); 
    $countsurf++;
  }
  return ( @packsurfsdata ); 
}

sub findextremes
{
  # THIS FINDS THE MAXIMA AND THE MINIMA FOR EACH COORDINATE FOR THE REQUESTED SURFACE
  my @xyzcoords = @_; 
  my @surfsdata;
  foreach my $coordsdataref ( @xyzcoords )
  {
    my @coordsdata = @$coordsdataref;
    my $count = 0;
    my @surfdata;
    foreach $coordstyperef (@coordsdata)
    {
      if ($count < 3)
      {
        my @coordstype = @$coordstyperef; 
        my $extreme1 = max(@coordstype); 
        my $extreme2 = min(@coordstype);     
        my $countpos = 0;
        my (@extreme1positions, @extreme2positions);
        foreach my $elt ( @coordstype )
        {
          if ( $elt ~~ $extreme1 )
          {
            push ( @extreme1positions, $countpos );
          }
          if ( $elt ~~ $extreme2 )
          {
            push ( @extreme2positions, $countpos );
          }
          $countpos++;
        }
        push ( @surfdata, [ [ $extreme1, [ @extreme1positions ] ], [ $extreme2, [ @extreme2positions ] ] ] ); 
        $count++;        
      }
      else
      {  
        if ( $surfdata[0][0][1] ~~ $surfdata[1][1][1] )
        {
          my $swap = $surfdata[1][1];
          $surfdata[1][1] = $surfdata[1][0];
          $surfdata[1][0] = $swap;
        }
        
        my $surfnum = $coordstyperef; 
        push ( @surfdata, $surfnum ); 
      }
    }
    push (@surfsdata, [ @surfdata ] ); 
  }
  return ( @surfsdata ); 
}

sub makecoordsgrid
{
  # THIS FORMS A GRID OVER EACH REQUESTED SURFACE
  my ($extremesref, $resolutionsref, $dirsvectorsrefsref) = @_;
  my @extremesdata = @$extremesref; 
  my @resolutions = @$resolutionsref; 
  my @dirsvectorsrefs = @$dirsvectorsrefsref; 
  my @wholegrid;
  my $countsurf = 0;
  foreach my $surfcase ( @extremesdata )
  {
    my $dirsvectorsref = $dirsvectorsrefs[$countsurf]; 
    my @surfdata = @$surfcase; 
    my $surf = pop @surfdata; 
    my @coordspoints;
    my $count = 0;
    foreach ( @surfdata )
    {
      my $extreme1 = $_->[0][0]; 
      my $extreme2 = $_->[1][0]; 
      my @extreme1positions = @{$_->[0][1]}; 
      my @extreme2positions = @{$_->[1][1]}; 
      my $resolution = $resolutions[$counter]; 
      my $diffextremes = ( $extreme1 - $extreme2 ); 
      my $variation = ( $diffextremes / ( $resolution + 1) ); 
      my @coordpoints;
      my $othercount = 1;
      while ( $othercount < ( $resolution +1 ) )
      {
        my $compoundvariation = ( $variation * $othercount ); 
        my $coordvalue = ( $extreme2 + $compoundvariation ); 
        push ( @coordpoints, $coordvalue ); 
        $othercount++;
      }
      push ( @coordspoints, [ @coordpoints ] ); 
      $count++;
    }
    push ( @coordspoints, $surf, $dirsvectorsref ); 
    push ( @wholegrid, [ @coordspoints ] ); 
    $countsurf++;
  }
  return(@wholegrid);
}

sub makegrid
{ # THIS CONVERTS THE GRID DATA IN VERTEX FORM
  my @gridcoords = @_; 
  my @gridsvertices; 
  foreach my $surfdataref ( @gridcoords )
  {
    my @xyzcoords;
    my @surfdata = @$surfdataref; 
    my @xdata = @{$surfdata[0]}; 
    my @ydata = @{$surfdata[1]}; 
    my @zdata = @{$surfdata[2]}; 
    my $surf = $surfdata[3]; 
    my $dirvectorsref = $surfdata[4]; 
    my $counter = 0;
    my @gridvertices;
    my ( @groups, @xyzdata );
    foreach my $xdatum (@xdata)
    {
      my $ydatum = $ydata[$counter];
      push ( @xyzdata, [ $xdatum, $ydatum ] ); 
      $counter++;
    }
    foreach my $elt (@xyzdata)
    {
      foreach my $zdatum ( @zdata )
      {
        my @group = @$elt;
        push ( @group, $zdatum ); 
        push ( @groups, [ @group ] ); 
      }
    }
    push ( @gridvertices, [ @groups ], $surf, $dirvectorsref ); 
    push ( @gridsvertices, [ @gridvertices ] ); 
  }
  return ( @gridsvertices );
}

sub adjust_dirvector
{  # THIS SCALES THE DIRECTION VECTORS TO EASE THE MANIPULATION OF THE GRIDS IN DETACHING THEM FROM SURFACES.
  my ( $vectorref, $distgrid ) = @_;
  my @vector = @$vectorref;
  my $denominator = ( 1 / $distgrid );
  my @adjusted_vector;
  foreach my $elt ( @vector )
  {
    my $adjusted_component = ( $elt / $denominator );
    $adjusted_component = sprintf ( "%.3f", $adjusted_component );
    push ( @adjusted_vector, $adjusted_component );
  }
  return ( @adjusted_vector );
}

sub adjustgrid
{  # THIS ADJUSTS THE GRIDS OF POINTS OVER THE REQUESTED SURFACES BY DETACHING THEM OF ABOUT 1 CM TOWARDS THE OUTSIDE.
  my ( $griddataref, $distgrid )  = @_;
  my @griddata = @$griddataref;
  my @adjustedsurfs;
  foreach my $elt ( @griddata )
  {
    my @surfdata = @$elt; 
    my @vertexdatarefs = @{$surfdata[0]}; 
    my $surfnum = $surfdata[1]; 
    my @dirvector = @{$surfdata[2]}; 
    my @adjusted_dirvector = adjust_dirvector( \@dirvector, $distgrid ); 
    my @adjustedsurfs;    
    foreach my $vertexref ( @vertexdatarefs )
    {
      my @vertexcoords = @$vertexref;
      my @adjustedvertex;
      $countcomp = 0;
      foreach my $el ( @vertexcoords )
      {
        my $component = $adjusted_dirvector[$countcomp]; 
        my $newel = ( $el + $component ); 
        push ( @adjustedvertex, $newel ); 
        $countcomp++; 
      }
      push ( @adjustedsurfs, [ @adjustedvertex ] );

    }
    push ( @adjusteddata, [ [ @adjustedsurfs ], $surfnum, [ @dirvector ] ] );
  }
  return ( @adjusteddata );
}

sub treatshdfile
{ # THIS PRE-PREPARES THE SHDA FILES IN MEMORY FOR USE.
  my @lines = @_;
  my @newlines;
  my $count = 0;
  foreach my $line ( @lines )
  {
    my $lineafter = $lines[ $count + 1 ]; #say REPORT"\$lineafter: $lineafter";
    my $linebefore = $lines[ $count - 1 ]; #say REPORT "\$linebefore: $linebefore";
    my $linecontrol = $line;
    if ( ( $lineafter =~ /# direct - surface/ ) or ( $lineafter =~ /# diffuse - surface/ ) )
    {
      $linecontrol = "";
    }
    elsif ( ( $line =~ /# direct - surface/ ) or ( $line =~ /# diffuse - surface/ ) )
    {
      chomp $linebefore; #say REPORT "\$linebefore__: $linebefore"; #say REPORT "\$line: $line";
      $line = "$linebefore" . " " . "$line" ; #say REPORT "\$joinline $line"; 
    }
        
    unless ( $linecontrol eq "" )
    {
      push ( @newlines, $line );
    }
    $count++;
  }
  return ( @newlines );
}
    

sub readshdfile
{ # THIS READS THE RELEVANT CONTENT OF THE SHDA FILE.
  my ( $shdfile ) = @_; #say REPORT "IN SUB \$shdfile : " . dump( $shdfile );
  my $shdafile = $shdfile . "a"; #say REPORT "\$shdafile : " . dump( $shdafile );
  if ( not ( -e $shdafile ) )#
  {
    say "\nExiting. A file \".shda\" must be present in the model folders for the operation to be performed.
    Now it isn't. To obtain that, a shading and insolation calculation must have been performed." and die;
  }
  my $tempfile = $shdafile; 
  $tempfile =~ s/\.shda/\.temp\.shda/ ; #say REPORT "\$tempfile : " . dump( $tempfile );
  
  open (SHDAFILE, "$shdafile") or die;
  my @shdalines = <SHDAFILE>; #say REPORT "\@shdalines : " . dump( @shdalines );
  close SHDAFILE,
  
  my (@filearray, @rawlines, @months);
  foreach my $line ( @shdalines )
  {
    push ( @rawlines, $line );
  }
  my @treatedlines = treatshdfile ( @rawlines ); #say REPORT "\@treatedlines " . dump(@treatedlines);
  
  foreach my $line ( @treatedlines )
  { # THIS READS THE ".shda" FILES.
    my @elts = split(/\s+|,/, $line);
    if ( $line =~ /\* month:/ )
    {
      my $month = $elts[2]; #say REPORT "\$month " . dump($month);
      push ( @months, $month );
    }
    push ( @filearray, [ @elts ] );
  } 
  
  open ( TEMP , ">$tempfile" ) or die;
  foreach my $line ( @treatedlines )
  {
    print TEMP $line;
  }
  close TEMP;
  return ( \@treatedlines, \@filearray, \@months );
}

sub tellsurfnames
{ # THIS RETURNS THE NAMES OF THE SURFACES.
  my ( $transpsurfsref, $geodataref ) = @_;
  my @transpsurfs = @$transpsurfsref; #say REPORT "HERE \@transpsurfs " . dump(@transpsurfs);
  my @geodata = @$geodataref; #say REPORT "\@geodata " . dump(@geodata);
  my ( @containernums, @containernames, @nums, @names );
  my $count = 0;
  foreach my $surf ( @transpsurfs )
  {
    foreach my $rowref ( @geodata )
    {
      my @row = @$rowref;
      if ( ( $surf eq $row[12] ) and ( $row[0] eq "*surf" ) )
      {
        push ( @nums, $surf );
        push ( @names, $row[1] );
      }
      $count++;
    }
  }
  return ( \@nums, \@names );
}

sub getsurfshd
{ # THIS RETURN ALL THE DATA NEEDED FROM THE ".shda" FILE.
  my ( $shdfilearrayref, $monthsref, $surfnumsref, $surfnamesref ) = @_;
  my @shdfilearray = @$shdfilearrayref; 
  my @months = @$monthsref; 
  my @surfnums = @$surfnumsref; 
  my @surfnames = @$surfnamesref; 

  my @yearbag;
  foreach my $month ( @months )
  {
    my $semaphore = 0;
    my @monthbag;
    foreach my $rowref ( @shdfilearray )
    {
      my @row = @$rowref; #say REPORT "\@row " . dump(@row);
      if ( ( $row[0] eq "*") and ( $row[1] eq "month:" ) and ( $row[2] eq "$month" ) )
      {
        $semaphore = 1; 
      }
      elsif ( ( $row[0] eq "*") and ( $row[1] eq "month:" ) and ( not ( $row[2] eq "$month" ) ) )
      {
        $semaphore = 0; 
      }
      foreach my $surfname ( @surfnames )
      {
        if ( ( $row[25] eq "diffuse") and ( $row[27] eq "surface") and ( $row[28] eq "$surfname" ) and ( $semaphore == 1 ) )
        {
          push ( @monthbag, [ [ @row[0..23] ], $surfname ] ); 
        }
      }
    }
    push ( @yearbag, [ [ @monthbag ], $month ] ); 
  } #say REPORT "\@yearbag " . dump(@yearbag);
  return ( @yearbag );    
}

sub checklight
{ # THIS LOOKS INTO THE "shda" DATA AND SEES WHEN DAYLIGHTING IS PRESENT. 
  my ( $shdfilearrayref, $monthsref ) = @_;
  my @shdfilearray = @$shdfilearrayref; 
  my @months = @$monthsref;

  my @yearbag;
  foreach my $month ( @months )
  {
    my @monthbag;
    my $countrow = 0;
    my $semaphore = 0;
    foreach my $rowref ( @shdfilearray )
    {
      my @row = @$rowref; 
      if ( ( $row[0] eq "*") and ( $row[1] eq "month:" ) and ( $row[2] eq "$month" ) )
      {
        $semaphore = 1; 
      }
      elsif ( ( $row[0] eq "*") and ( $row[1] eq "month:" ) and ( not ( $row[2] eq "$month" ) ) )
      {
        $semaphore = 0;
      }
      
      if ( ( $row[0] eq "surfaces") and ( $row[1] eq "insolated") and ( $semaphore == 1 ) )
      {
        my @bag;
        #say REPORT "HERE IT IS: \@{ $shdfilearray[ $countrow + 1 ] } " . dump ( @{ $shdfilearray[ $countrow + 1 ] } );
        foreach my $el ( @{ $shdfilearray[ $countrow + 1 ] } )
        {
          if ( $el < 0 )
          { #say REPORT "FOUND OFF";
            $el = 1;
            push ( @bag, $el );
          }
          else
          { #say REPORT "FOUND ON";
            $el = 0;
            push ( @bag, $el );
          }
        }
        push ( @monthbag, [ @bag ] );
      }
      $countrow++;
    }
    push ( @yearbag, [ [ @monthbag ], $month ] ); 
  } #say REPORT "\@yearbag " . dump(@yearbag);
  return ( @yearbag );   
}

sub tellradfilenames
{ # THIS RETURNS THE NAMES OF THE RADIANCE FILES.
  my ( $path, $conffile_fict1, $conffile_fict2, $conffile_fict3 ) = @_; #say REPORT "\$path " . dump($path); 
  #say REPORT "\$conffile_fict1 " . dump($conffile_fict1);#say REPORT "\$conffile_fict2 " . dump($conffile_fict2);#say REPORT "\$conffile_fict3 " . dump($conffile_fict3);
  my @confs = ( $conffile_fict1, $conffile_fict2, $conffile_fict3 );
  my @result;
  foreach my $conf ( @confs )
  {
    my $confstripped = $conf;
    $confstripped =~ s/$path\/cfg\///;
    $confstripped =~ s/.cfg//;
    my $radoct = "$confstripped" . "_Extern.oct";
    my $rcffile = "$confstripped" . ".rcf" ;
    push ( @result, [ $conf, $radoct, $rcffile ] );
  }
  return( @result );
}

sub setrad
{ #say REPORT "BEGIN SETRAD\n"; print "BEGIN SETRAD\n";
  # THIS CREATES THE RADIANCE SCENES.
  my ( $conffile, $radoctfile, $rcffile, $path, $monthnum, $day, $hour, $countfirst, $exportconstrref, $exportreflref ) = @_; #print REPORT "SETRAD\n";
  my $radoctroot = $radoctfile;
  $radoctroot =~ s/$radoctfile/\.oct/ ;
  my $skyfile = $rcffile;
  $skyfile =~ s/rcf/sky/ ;

  my $moment;
  
  if ( ( ( $monthnum == 12 ) or ( $monthnum == 1 ) or ( $monthnum == 11 ) or ( $monthnum == 2 ) ) and ( $hour < 11 ) )
  { $moment = "a"; }
  elsif ( ( ( $monthnum == 12 ) or ( $monthnum == 1 ) or ( $monthnum == 11 ) or ( $monthnum == 2 ) ) and ( ( $hour == 11 ) or ( $hour == 12 ) or ( $hour == 13 ) ) )
  { $moment = "b"; }
  elsif  ( ( ( $monthnum == 12 ) or ( $monthnum == 1 ) or ( $monthnum == 11 ) or ( $monthnum == 2 ) ) and ( $hour > 13 ) )
  { $moment = "c"; }
  elsif ( ( ( $monthnum == 3 ) or ( $monthnum == 4 ) or ( $monthnum == 9 ) or ( $monthnum == 10 ) ) and ( $hour < 11 ) )
  { $moment = "d"; }
  elsif ( ( ( $monthnum == 3 ) or ( $monthnum == 4 ) or ( $monthnum == 9 ) or ( $monthnum == 10 ) ) and ( ( $hour == 11 ) or ( $hour == 12 ) or ( $hour == 13 ) ) )
  { $moment = "e"; }
  elsif  ( ( ( $monthnum == 3 ) or ( $monthnum == 4 ) or ( $monthnum == 9 ) or ( $monthnum == 10 ) ) and ( $hour > 13 ) )
  { $moment = "f"; }
  elsif  ( ( ( $monthnum == 5 ) or ( $monthnum == 6 ) or ( $monthnum == 7 ) or ( $monthnum == 8 ) ) and ( $hour < 11 ) )
  { $moment = "g"; }
  elsif  ( ( ( $monthnum == 5 ) or ( $monthnum == 6 ) or ( $monthnum == 7 ) or ( $monthnum == 8 ) ) and ( ( $hour == 11 ) or ( $hour == 12 ) or ( $hour == 13 ) ) )
  { $moment = "h"; }
  elsif  ( ( ( $monthnum == 5 ) or ( $monthnum == 6 ) or ( $monthnum == 7 ) or ( $monthnum == 8 ) ) and ( $hour > 13 ) )
  { $moment = "i"; }
  
  
  #if ( not ( $countfirst == 0 ) )
  #{
    #say REPORT "NOW IN SETRAD";
    
    say REPORT "cd $path/rad/
e2r -file $conffile -mode text<<YYY

b
$rcffile
a
a
$moment
1
n
d

d
$day $monthnum $hour
g
-
h
c
a
d
a
f
c
h
y
>
$riffile
-
-
YYY
";

`cd $path/rad/
e2r -file $conffile -mode text<<YYY

b
$rcffile
a
a
$moment
1
n
d

d
$day $monthnum $hour
g
-
h
c
a
d
a
f
c
h
y
>
$riffile
-
-
YYY
`; #say REPORT "END SETRAD\n"; print "END SETRAD\n"

#adjust_radmatfile( $exportconstrref, $exportreflref, $conffile, $path );

}


sub setroot
{ # THIS SETS THE MODELS' ROOT NAME.
  my ( $conffile, $path ) = @_; #say REPORT "BEGIN SETROOT\n"; print "BEGIN SETROOT\\n";
  my $rootname = $conffile; #say REPORT "SETROOT\n"; 
  $rootname =~ s/$path\/cfg\///;
  $rootname =~ s/\.cfg//;
  #say REPORT "NOW IN SETROOT";
print REPORT "cd $path/cfg
prj -file $conffile -mode text<<YYY

s

$rootname




-

YYY
";

`cd $path/cfg
prj -file $conffile -mode text<<YYY

s

$rootname

m
c
b
#
y
-
-
-
-

YYY
`; #say REPORT "END SETROOT\n"; say "END SETROOT\n"; 
}

sub populatelight
{ # THIS POPULATES THE DATA STRUCTURE DEDICATED TO THE SIGNAL THE DAYLIGHTED  HOURS.
  my @daylighthoursarr = @_;
  my %daylighthours;
  my $count = 0;
  foreach my $monthref ( @daylighthoursarr )
  {
    my @monthdata = @$monthref;
    my $month = $monthdata[1];
    $month =~ s/`//g;
    my @lithours = @{$monthdata[0][0]};
    $daylighthours{$month} = [ @lithours ] ;
    $count++;
  } #say REPORT "\%daylighthours\ " . dump(%daylighthours);
  return ( %daylighthours );
}


sub deg2rad 
{
	my $degrees = shift;
	return ( ( $degrees / 180 ) * 3.14159265358979 );
}

sub rad2deg 
{
	my $radians = shift;
	return ( ( $radians / 3.14159265358979 ) * 180 ) ;
}

sub rotate2d
{ # SELF-EXPLAINING
    my ( $x, $y, $angle ) = @_;
    $angle = deg2rad( $angle );
    my $x_new = cos($angle)*$x - sin($angle)*$y;
    my $y_new = sin($angle)*$x + cos($angle)*$y;
  return ( $x_new, $y_new);
}

sub getdirvectors
{ # THIS GETS THE NEEDED DIRECTION VECTORS AT EACH GRID POINT DEPENDING FROM THE LAUNCH SETTINGS.
   ( $basevectorsref, $dirvectorref, $pointcoordsref ) = @_;
   my @basevectors = @$basevectorsref;; 
   my @dirvector = @$dirvectorref; 
   my @topcoords = @{$basevectors[0]};
   my @newdirvectors;
   my $xbase = $topcoords[0]; 
   my $ybase = $topcoords[1]; 
   my $zbase = $topcoords[2]; 
   my $xnew = $dirvector[0]; 
   my $ynew = $dirvector[1]; 
   my $znew = $dirvector[2]; 
   my $anglebasexz = acos($xbase); 
   my $anglebaseyz = acos($zbase); 
   my $anglenewxz = acos($xnew); 
   my $anglenewyz = acos($znew); 
   my $anglediffxz = ( $anglenewxz - $anglebasexz );  
   my $anglediffyz = ( $anglenewyz - $anglebaseyz ); 
   foreach my $eltsref ( @basevectors )
   {
     my @elts = @$eltsref;
     my ( $x, $y, $z ) = @elts ;
     my ( $x_ok, $tempy ) = rotate2d( $x, $y, $anglediffxz );
     my ( $y_ok, $z_ok ) = rotate2d( $tempy, $z, $anglediffyz );
     $x_ok = sprintf ( "%.3f", $x_ok );
     $y_ok = sprintf ( "%.3f", $y_ok );
     $z_ok = sprintf ( "%.3f", $z_ok );
     push ( @newdirvectors, [ $x_ok, $y_ok, $z_ok ] );
   } #say REPORT "\@newdirvectors\: " . dump(@newdirvectors); 
   return ( @newdirvectors );
}

sub pursue
{ # THIS CALCULATES THE IRRADIANCES BY THE MEANS OF RADIANCE.
  # RADIANCE EXAMPLE: echo 1 -0.01 2 0 -1 0 | rtrace  -I -ab 2 -h /home/luca/boxform/rad/boxform_fict1_Extern.oct | rcalc -e '$1=179*(.265*$1+.670*$2+.065*$3)'
  my $exportconstrref = shift, 
  my $exportreflref = shift; 
  my $conffile = shift;
  my $basevectorsref = shift;
  my @basevectors = @$basevectorsref;
  my $path = shift; #say REPORT "\$path\ " . dump($path);
  my $fict1ref = shift; #say REPORT "\$fict1ref\ " . dump($fict1ref);
  my $fict2ref = shift; #say REPORT "\$fict2ref\ " . dump($fict2ref);
  my $fict3ref = shift; #say REPORT "\$fict3ref\ " . dump($fict3ref);
  my $bounceambnum = shift;  #say REPORT "\$bounceambnum\ " . dump($bounceambnum);
  my $bouncemaxnum = shift;  #say REPORT "\$bouncemaxnum\ " . dump($bouncemaxnum);
  my ( $conffile_fict1, $radoctfile_fict1, $rcffile_fict1 ) = @$fict1ref; 
  my ( $conffile_fict2, $radoctfile_fict2, $rcffile_fict2 ) = @$fict2ref;
  my @conffiles = ( $conffile_fict1, $conffile_fict2, $conffile_fict3 ); #say REPORT "\@conffiles\ " . dump(@conffiles);
  my @radoctfiles = ( $radoctfile_fict1, $radoctfile_fict2  ); #say REPORT "\@radoctfiles\ " . dump(@radoctfiles);
  my @rcffiles = ( $rcffile_fict1, $rcffile_fict2 ); #say REPORT "\@rcffiles\ " . dump(@rcffiles);
  
  my @zonedata = @_; #say REPORT "\@zonedata\ " . dump(@zonedata);
  my $fileroot = $radoctfile_fict1; 
  $fileroot =~ s/_fict1_Extern.oct//; #say REPORT "\$fileroot\ " . dump($fileroot);
  my ( %irrs, %irrs_dir, %irrs_amb);
  my $setoldfiles = "on";
    
  my ( $casedataref , $gridpointsref, $shdsurfdataref, $daylighthoursref, $shdfilearrayref  ) = @{ $zonedata[0] };
  my ( $zonenum, $geofile, $constrfile, $shdfile ) = @$casedataref; 
  my @gridpoints = @$gridpointsref; #say REPORT "\@gridpoints\ " . dump(@gridpoints);
  my @shdsurfdata = @$shdsurfdataref; #say REPORT "\@shdsurfdata\ " . dump(@shdsurfdata);
  my @daylighthoursarr = @$daylighthoursref; #say REPORT "\@daylighthoursarr\ " . dump(@daylighthoursarr);
  my @shdfilearray = @$shdfilearrayref; #say REPORT "\@shdfilearray\ " . dump(@shdfilearray);
  
  my $countfirst = 0;
  my $countrad = 0;
  foreach my $radoctfile ( @radoctfiles )
  { 
    opendir( DIR, "$path/rad/" );
    my @names = grep( /\.rcf/ , readdir(DIR) );
    closedir( DIR );
    #if ( @names )
    #{
    #  `rm $path/rad/*`;
    #  `rm $path/rad/*`;
    #   print REPORT "rm $path/rad/*";
    #}

    my $countmonth = 0;
    foreach my $monthsdataref ( @daylighthoursarr )
    {   
      my @monthsdata = @$monthsdataref; 
      my @hourslight = @{$monthsdata[0][0]}; 
      my $month = $monthsdata[1]; 
      $month =~ s/`//g; 
      my $monthnum = getmonthnum( $month );          
      my $day = $days_inmonths{ $month }; 
      my ( @surftests, @surftests_dir, @surftests_amb );
      
      my $countsurf = 0;
      foreach my $surfref ( @gridpoints )
      {  
        my @surfdata = @$surfref;
        my @pointrefs = @{ $surfdata[0] }; 
        my $surfnum = $surfdata[1]; 
        my @dirvector = @{ $surfdata[2] }; 
        my ( $dirvectorx, $dirvectory, $dirvectorz ) = @dirvector;          
        my $conffile = $conffiles[$countrad]; 
        my $radoctfile = $radoctfiles[$countrad]; 
        my $rcffile = $rcffiles[$countrad]; 
        my $radmatfile = $radoctfile;
        $radmatfile =~ s/\.oct/\.mat/ ;
        my $radmatcopy = $radmatfile . ".copy";

        my $countlithour = 0;
        my $counthour = 0; 
        foreach my $hourlight ( @hourslight )
        {    
          if ( $hourlight != 1 )
          { 
            $countlithour++;
            my $hour = ( $counthour + 1) ;
            
            my $countpoint = 0;
            #say REPORT "\$countmonth\ " . dump($countmonth);
            #say REPORT "\$countsurf\ " . dump($countsurf);
            if ( ( $countmonth == 0 ) and ( $countsurf == 0 ) and ( $countlithour == 1 ) ) ### and ( $countpoint == 0 ) and ( $setoldfiles = "on" )
            { 
              #createrad( $conffile, $radoctfile, $rcffile, $path );
              
              setroot( $conffile, $path);
              setrad( $conffile, $radoctfile, $rcffile, $path, $monthnum, $day, $hour, $countfirst, $exportconstrref, $exportreflref );
              
              if ( $countrad == 1)
              { 
                adjust_radmatfile( $exportconstrref, $exportreflref, $conffile, $path );
                `cp -f $path/rad/$radmatfile $path/rad/$radmatcopy`;
                say REPORT "cp -f $path/rad/$radmatfile $path/rad/$radmatcopy";
              
                open ( FIXLIST, ">$path/rad/fixl.pl" ) or die( $! );
                print FIXLIST "$path/rad/$radmatfile\n";
                print FIXLIST "$path/rad/$radmatcopy\n";
                close FIXLIST;
              }
              
              #say REPORT "ABOUT TO CALL CREATERAD";
              $setoldfiles = "off";
            }
            
            #my $d = File::Modified->new(files=>[$radmatfile] );  #STARTDAEMON
            #while ( $go == 1 ) 
            #{
            #my ( @changes ) = $d->changed;
            #if ( @changes ) 
            #{
            #    `cp -f $radmatcopy $radmatfile`;
            #    say REPORT "cp -f $radmatcopy $radmatfile";
            #    $d->update();
            #  }
            #  sleep 0.05 ;
            #}
            
            #if ( $countrad == 1)
            #{
            # # my $go = 1;
            #  my $monitor = File::Monitor::Lite->new( in => "$path/rad/", name => "$radmatfile" );
            #  while ( $monitor->check() and sleep 0.01 )
            #  {
            #    if ( $monitor->modified )
            #    {
            #       `cp -f $path/rad/$radmatcopy $path/rad/$radmatfile`;
            #       say REPORT "cp -f $path/rad/$radmatcopy $path/rad/$radmatfile";
            #    }
            #  }
            #}
            
            #say REPORT "\$countrad : $countrad";
            #if ( $countrad == 1)
            #{
            #  `perl ./hack.pl "$path" "$radmatfile" "$radmatcopy" &`;
            #  say REPORT "perl ./hack.pl \"$path\" \"$radmatfile\" \"$radmatcopy\" &\n";
            #}
            
            setrad( $conffile, $radoctfile, $rcffile, $path, $monthnum, $day, $hour, $countfirst, $exportconstrref, $exportreflref );                 
            
            #if ( $countrad == 1)
            #{
            #  $go = 2; #CLOSEDAEMON  
            #}
            
            #$countfirst++;    
            
            foreach my $pointref ( @pointrefs )
            {    
              my @pointcoords = @$pointref; 
              my ( $xcoord, $ycoord, $zcoord ) = @pointcoords;
              my $raddir = "$path/rad/";
              my $cfgpath = "$path/cfg/";
              my @dirvgroup = getdirvectors ( \@basevectors, \@dirvector );
              my $countdirvec = 0;
              foreach my $dirvector ( @dirvgroup )
              { 
                my ( $valstring, $x, $y, $z, $irr );
                if ( ( $countrad == 0 ) or ( $countrad == 1 ) )
                {
                  $valstring = `cd $raddir \n echo $xcoord $ycoord $zcoord $dirvectorx $dirvectory $dirvectorz | rtrace  -I -ab $bounceambnum -lr $bouncemaxnum -h $radoctfile`; say REPORT "TO SHELL: cd $raddir \n echo $xcoord $ycoord $zcoord $dirvectorx $dirvectory $dirvectorz | rtrace  -I -ab $bounceambnum -lr $bouncemaxnum -h $radoctfile";
		  ( $x, $y, $z ) = ( $valstring =~ m/(.+)\t(.+)\t(.+)\t/ ); #say REPORT "VALSTRING: " . dump( $valstring ); #say REPORT "x: $x, y: $y, z: $z"; 
                  $irr = ( 179 * ( ( .265 * $x ) + ( .670 * $y ) + ( .065 * $z ) ) ); 
                }

                push ( @surftests, $irr );

                $countdirvec++;
              }
              $countpoint++;
            } 
            my $meanvaluesurf;
            if ( @surftests )
            { 
              $meanvaluesurf = _mean_( @surftests ); say "Calculating irradiance: $meanvaluesurf, for surface $surfnum, zone $zonenum, month $monthnum, day $day, hour $hour, octree $radoctfile.\n" ;
              #say REPORT "Calculating irradiance: $meanvaluesurf, for surface $surfnum, zone $zonenum, month $monthnum, day $day, hour $hour, octree $radoctfile.\n" ;

            } 
                          
            if ( $meanvaluesurf and $surfnum and $hour )
            {
              $irrs{ $zonenum }{ $countrad + 1 }{ $monthnum }{ $surfnum }{ $hour }{ meanirr } = $meanvaluesurf;
            }
          }
          $counthour++;      
        }
        $countsurf++;
      }
      $countmonth++;
    }
    $countrad++;
  } #say REPORT " HERE PURSUE \%irrs\: " . dump(%irrs);
  return ( \%irrs ); 
}

sub cleanblanks
{ # SELF-EXPLAINING.
  my @arr = @_;
  my @box;
  my $count = 0;
  foreach my $el ( @arr )
  {
    unless ( $el eq "" )
    {
      push ( @box, $el );
    }
    $count++;
  }
  return( @box );
}

sub createconstrdbfile
{ # THIS CREATES THE CONSTRUCTION DB FILE OF THE FICTIOTIOUS ESP-r MODELS.
  my ( $constrdbfile, $constrdbfile_fict, $obsconstrsetref ) = @_; #say REPORT "BEGINNING: \$constrdbfile, $constrdbfile";
  my @obsconstrset = @$obsconstrsetref; #say REPORT "\@obsconstrset " . dump(@obsconstrset);
  @obsconstrset = uniq( @obsconstrset );
  my ( @bigcopy, @updatedlines );
  open ( DBFILE, "$constrdbfile" ) or die; 
  my @lines = <DBFILE>; #say REPORT "\@lines " . dump(@lines);
  close DBFILE;  
  
  my $topline;
  my $countline = 0;
  #say REPORT "BEGUN createconstrdbfile ";
  foreach my $line ( @lines )
  { #THIS PUSHES IN @UPDATEDLINES THE CONSTR DATABASE EXCEPTED THE FIRST LINES (HEADER LINES)
    my @row = split( /\s+|,/ , $line); #say REPORT "countline: $countline, row: " . dump( @row );
    @row = cleanblanks( @row ); #say REPORT "countline: $countline, row: " . dump( @row );
    my ( $oldnumber, $newnumber );
    my $atline;
    if ( $line =~ /\# no of composites/ ) 
    {
      $atline == $countline;
      $oldnumber = $row[0]; #say REPORT "oldnumber: $oldnumber";
      $newnumber = ( $oldnumber + scalar( @obsconstrset ) ); #say REPORT "newnumber: $newnumber";
      $line =~ s/$oldnumber/$newnumber/;
      push ( @updatedlines, $line );
    }
    else 
    {
      push ( @updatedlines, $line );
    }
    $countline++;
  } #say REPORT "updatedlines " . dump(@updatedlines);
  
  my $coun = 0;
  foreach my $el ( @obsconstrset )
  { #FOREARCH MATERIAL USED IN THE OBSTRUCTIONS, PUSHES THE CONSTRUCTION SOLUTIONS IN WHICH IT IS USED IN @COPY, AND PUSHES EACH [ @COPY ] IN @BIGCOPY
    my @copy;
    my $semaphore = 0;
    $countel = 0;
    $countline = 0;
    foreach my $line ( @updatedlines )
    {
      my @row = split( /\s+|,/ , $line); #say REPORT "countline: $countline, row: " . dump( @row );
      @row = cleanblanks( @row ); #say REPORT "countline: $countline, row: " . dump( @row );
     # if ( $countline > 2 ) #WHY IS THIS?
     # {
        if ( $el eq $row[1] )
        {
          $semaphore = 1; #say REPORT "HIT. semaphore on";
        }
          
        if ( ( $semaphore == 1 ) and ( $countel == 0) )
        {
          push ( @copy, "# layers  description   optics name   symmetry tag\n" );
          push ( @copy, $line ); #say REPORT "pushing first, $countel"; #say REPORT "\@copy " . dump(@copy);
          $countel++;
        } 
        elsif ( ( $semaphore == 1 ) and ( $countel > 0) )
        {
          push ( @copy, $line ); 
          if (  ( $row[0] eq "#" ) and ( $row[1] eq "layers" ) and ( $row[2] eq "description" )  )
          {
            pop(@copy);
            $semaphore = 0; #say REPORT "semaphore off";
          }
          $countel++;
        }
        
      #}
      $countline++;
    }
    say REPORT "\@copy " . dump(@copy);
    #if ( $coun == $#obsconstrset ) 
    #{
    #  @bigcopy = [ @copy ];
    #}
    push ( @bigcopy, [ @copy ] ); #say REPORT "\@bigcopy " . dump(@bigcopy);
    $coun++;
  } #say REPORT "\@bigcopy" . dump(@bigcopy);
  
  my $cn = 0;
  my ( @materials, @newmaterials, @newcopy, @newbigcopy );
  my ( $newmatinssurf, $newmatextsurf );
  my %exportconstr;
  foreach my $copyref ( @bigcopy )
  {  
    my @constrlines = @$copyref; 
    my $firstrow = $constrlines[1]; #say REPORT "\$firstrow " . dump($firstrow);
    my @row = split ( /\s+|,/ , $firstrow );
    @row = cleanblanks( @row );
    my $constrname = $row[1];  #say REPORT "\$constrname " . dump($constrname);
    my $newconstrname = $constrname;
    $newconstrname =~ s/\w\b// ;  
    $newconstrname =~ s/\w\b// ;  
    $newconstrname = "f_" . "$newconstrname"; #say REPORT "\$newconstrname " . dump($newconstrname);
    
    my $intlayer = $constrlines[3]; #say REPORT "\$intlayer " . dump($intlayer);
    my @row = split ( /\s+|,/ , $intlayer );
    @row = cleanblanks( @row ); 
    my $matintlayer = $row[2]; #say REPORT "\$matintlayer " . dump($matintlayer);
    my $newmatintlayer = $matintlayer;
    $newmatintlayer =~ s/\w\b// ;  
    $newmatintlayer =~ s/\w\b// ;  
    $newmatintlayer = "f_" . "$newmatintlayer"; #say REPORT "\$newmatintlayer " . dump($newmatintlayer);
    my $extlayer = $constrlines[$#constrlines]; #say REPORT "\$extlayer " . dump($extlayer);
    my @row = split ( /\s+|,/ , $extlayer );
    @row = cleanblanks( @row ); 
    my $matextlayer = $row[2]; #say REPORT "\$matextlayer " . dump($matextlayer);
    my $newmatextlayer = $matextlayer;
    $newmatextlayer =~ s/\w\b// ; 
    $newmatextlayer =~ s/\w\b// ;  
    $newmatextlayer = "f_" . "$newmatextlayer"; #say REPORT "\$newmatextlayer $newmatextlayer";
    push ( @materials, $matintlayer, $matextlayer );  #say REPORT "\$matintlayer $matintlayer"; #say REPORT "\$matextlayer $matextlayer";
    push ( @newmaterials, $newmatintlayer, $newmatextlayer );  #say REPORT "\$newmatintlayer $newmatintlayer"; #say REPORT "\$newmatextlayer $newmatextlayer";

    
    $constrlines[1] =~ s/$constrname/$newconstrname/g; #say REPORT "\$constrlines[1] " . dump( $constrlines[1] );
    $constrlines[3] =~ s/$matintlayer/$newmatintlayer/g; #say REPORT "\$constrlines[3] " . dump( $constrlines[3] );
    $constrlines[$#constrlines] =~ s/$matextlayer/$newmatextlayer/g; #say REPORT "\$constrlines[\$#constrlines] " . dump($constrlines[$#constrlines]);
    foreach my $line ( @constrlines )
    {
      push ( @newcopy, $line );
    }
    @newbigcopy = [ @newcopy ] ;
    #push ( @newbigcopy, [ @newcopy ] );
    $exportconstr{ $newconstrname }{ extlayer } = $newmatextlayer;
    $exportconstr{ $newconstrname }{ intlayer } = $newmatintlayer;
    $cn++;
  } #say REPORT "DONE 1";
  
  @materials = uniq( @materials ); #say REPORT "materials: " . dump( @materials );
  @newmaterials = uniq( @newmaterials ); #say REPORT "newmaterials: " . dump( @newmaterials );
  #say REPORT "newbigcopy: " . dump( @newbigcopy );
  
  my %newmatnums;
  my $countmat = 1;
  foreach ( @newmaterials )
  {
    $newmatnums{$_} = $countmat;
    $countmat++;
  } #say REPORT "\%newmatnums " . Dumper( %newmatnums );
  
  my %matnums;
  $countmat = 1;
  foreach ( @materials )
  {
    $matnums{$_} = $countmat ;
    $countmat++;
  } #say REPORT "\%matnums " . Dumper( %matnums );
  
  my ( @lastbigcopy );
  $countmat = 1;
  foreach my $copyref ( @newbigcopy )
  { #say REPORT "DOING 2";
    my ( @lastcopy );
    my @constrlines = @$copyref; 
    my $intlayer = $constrlines[3]; #say REPORT "\$intlayer " . dump($intlayer);
    my @row = split ( /\s+|,/ , $intlayer );
    @row = cleanblanks( @row ); 
    my $matintlayernum = $row[0]; #say REPORT "\$matintlayernum " . dump($matintlayernum);
    my $matintlayer = $row[2]; #say REPORT "\$matintlayer " . dump($matintlayer);

    my $extlayer = $constrlines[$#constrlines]; #say REPORT "\$extlayer " . dump($extlayer);
    my @row = split ( /\s+|,/ , $extlayer );
    @row = cleanblanks( @row ); 
    my $matextlayernum = $row[0];
    my $matextlayer = $row[2]; #say REPORT "\$matextlayer " . dump($matextlayer);
    
    
    my $newmatnumint = $newmatnums{$matintlayer}; #say REPORT "\$newmatnumint " . dump($newmatnumint); say REPORT " had " . dump ($newmatnums{ $matintlayer });
    my $newmatnumext = $newmatnums{$matextlayer}; #say REPORT "\$newmatnumext " . dump($newmatnumext); say REPORT " had " . dump ($newmatnums{ $matextlayer });
    $constrlines[3] =~ s/$matintlayernum/$newmatnumint/g; #say REPORT "\$constrlines[3] " . dump( $constrlines[3] ); 
    $constrlines[$#constrlines] =~ s/$matextlayernum/$newmatnumext/g; #say REPORT "\$constrlines[\$#constrlines] " . dump($constrlines[$#constrlines]);
    foreach my $line ( @constrlines )
    {
      push ( @lastcopy, $line );
    }
    push ( @lastbigcopy, [ @lastcopy ] );
  } #say REPORT "DONE 2"; say REPORT "lastbigcopy: " . dump( @lastbigcopy );
  
  foreach ( @lastbigcopy )
  {
    foreach ( @$_ )
    {
      push ( @updatedlines, $_ )
    }
  }
  
  open ( CONSTRDBFILE_FICT, ">$constrdbfile_fict" ) or die;
  foreach ( @updatedlines )
  {
    
    print CONSTRDBFILE_FICT $_;
  } #say REPORT "\@updatedlines " . dump( @updatedlines ); 
  close CONSTRDBFILE_FICT; 
  #say REPORT "\%exportconstr: " . dump( %exportconstr );
  return ( \@materials, \@newmaterials, \%matnums, \%newmatnums, \%exportconstr );    
}



sub compareirrs
{ # THIS COMPARES THE IRRADIANCES TO OBTAIN THE IRRADIANCE RATIOS.
  my ( $zonefilelistsref, $irrsref ) = @_;  
  my %zonefilelists = %$zonefilelistsref; #say  REPORT "HERE IN COMPAREIRRS \%zonefilelists\: " . Dumper(%zonefilelists);
  my %irrs = %$irrsref; #say  REPORT "HERE IN COMPAREIRRS \%irrs\: " . Dumper(%irrs);
  my %irrvars;
  foreach my $zonenum ( sort {$a <=> $b} ( keys %irrs ) )
  {  #say REPORT "IN COMPAREIRRS - FOREACH zonenum\: $zonenum" ;
    my $shdfile = $zonefilelists{ $zonenum }{ shdfile }; #say REPORT "IN COMPAREIRRS \$shdfile\: " . Dumper($shdfile);
    foreach my $monthnum ( sort {$a <=> $b} ( keys %{ $irrs{ $zonenum }{ 1 } } ) )
    {  #say REPORT "IN COMPAREIRRS - FOREACH MONTHNUM\: $monthnum" ;
      foreach my $surfnum ( sort {$a <=> $b} ( keys %{ $irrs{ $zonenum }{ 1 }{ $monthnum } } ) )
      {  #say REPORT "IN COMPAREIRRS - FOREACH surfnum\: $surfnum" ;
        foreach my $hour ( sort {$a <=> $b} ( keys %{ $irrs{ $zonenum }{ 1 }{ $monthnum }{ $surfnum } } ) )
        {  #say REPORT "IN COMPAREIRRS - FOREACH hour\: $hour" ;
          my $surfirr = $irrs{ $zonenum }{ 1 }{ $monthnum }{ $surfnum }{ $hour }{ meanirr }; #say REPORT "\$surfirr " . dump($surfirr); #say REPORT "\$zonenum " . dump($zonenum); #say REPORT "\$monthnum " . dump($monthnum);#say REPORT "\$surfnum " . dump($surfnum);#say REPORT "\$hour " . dump($hour);
	  my $whitesurfirr = $irrs{ $zonenum }{ 2 }{ $monthnum }{ $surfnum }{ $hour }{ meanirr }; #say REPORT "\$whitesurfirr " . dump( $whitesurfirr );#say REPORT "\$zonenum " . dump($zonenum);#say REPORT "\$monthnum " . dump($monthnum);#say REPORT "\$surfnum " . dump($surfnum);#say REPORT "\$hour " . dump($hour);
	  my $surfirr_amb = $irrs{ $zonenum }{ 3 }{ $monthnum }{ $surfnum }{ $hour }{ meanirr }; #say REPORT "\$surfirr_amb " . dump( $surfirr_amb );#say REPORT "\$zonenum " . dump($zonenum);#say REPORT "\$monthnum " . dump($monthnum);#say REPORT "\$surfnum " . dump($surfnum);#say REPORT "\$hour " . dump($hour);
          my $irrratio = ( $whitesurfirr / $surfirr ); #say REPORT "HERE IN COMPAREIRRS \$irrratio " . dump( $irrratio );#say REPORT "HERE IN COMPAREIRRS \$zonenum " . dump($zonenum);#say REPORT "\$monthnum " . dump($monthnum);#say REPORT "\$surfnum " . dump($surfnum);#say REPORT "\$hour " . dump($hour);
				        
          $irrvars{ $zonenum }{ $monthnum }{ $surfnum }{ $hour }{ irrvar } = $irrratio;
          $countsurf++;
        }          
        $counthour++;
      }
      $countmonth++;
    }
    $countzone++;
  } #say REPORT  "HERE IN COMPAREIRRS \%irrvars " . dump(%irrvars);
  return ( \%irrvars ); 
}


sub fillhours
{ # THIS COMPLETES THE FILLING OF THE DATA STRUCTURES GIVING INFORMATION ABOUT THE DAYLIGHT HOURS.
  my ( $newhourvalsref, $monthname, $daylighthoursref ) = @_;  
  my @hadhours = @$newhourvalsref; 
  my %lithours = %$daylighthoursref; 
  my @monthhours = @{ $lithours{ $monthname } }; 
  my @values;
  
  my $sunhoursnum = 0;
  foreach my $lightcond ( @monthhours )
  {
    unless ( $lightcond == 1 )
    {
      $sunhoursnum++;
    }
  }
  
  if ( $sunhoursnum == scalar( @hadhours ) )
  {
    my $counthr = 1;
    my $countlit = 0;
    foreach my $lightcond ( @monthhours )
    {
      if ( $lightcond == 1 )
      {
        push ( @values, "1.0000" );
      }
      else
      {
        push ( @values, $hadhours[ $countlit ] ); 
        $countlit++;
      }
      $counthr++;
    } #say REPORT "VALUES FILLHOURS @values";
    return ( @values );
  }
}


sub modifyshda
{ # THIS MODIFIES THE ".shda" FILE ON THE BASIS OF THE IRRADIANCE RATIOS:
  my ( $comparedirrsref, $surfslistref, $zonefilelistsref, $shdfileslistref, $daylighthoursref, $irrvarsref, $threshold, $tempmod, $tempreport, $elm ) = @_;
  my %surfslist = %$surfslistref; #say REPORT "\%surfslist\: " . dump(%surfslist);
  my %zonefilelists = %$zonefilelistsref; #say REPORT "\%zonefilelists\: " . dump(%zonefilelists);
  my %shdfileslist = %$shdfileslistref;  #say REPORT "\%shdfileslist\: " . dump(%shdfileslist);
  my %daylighthours = %$daylighthoursref;  #say REPORT "\%daylighthours\: " . dump(%daylighthours);
  my %irrvars = %$irrvarsref; #say REPORT "\%irrvars\: " . dump(%irrvars);
  my ( @printcontainer, @monthnames, @pushmodline, @pushreportline, @mainbag, @mainoriginal );
                      
  foreach my $zonenum ( sort {$a <=> $b} ( keys %irrvars ) )
  {  #say REPORT "FROM MODIFYSHDA: - FOREACH \$zonenum\: $zonenum" ;
    my $inlinesref = $shdfileslist{ $zonenum }; 
    my @inlines = @$inlinesref; #say REPORT "\@inlines\: " . dump(@inlines);
    my $semaphore = 0;
    my ( $readmonthname, $readmonthnum ); #say REPORT "\THE MODIFIED SHADE FILE DERIVING FROM THE .shda FILE WILL SAVEED AS .mod.shda FILE.";
    my $countline = 1;
    foreach my $line ( @inlines )
    {
      my $line2;
      my @row = split( /\s+|,/ , $line); 
      my ( $readsurfname, $readsurfnum );
      if ( ( $row[0] eq "*" ) and ( $row[1] eq "month:" ) )
      {
        $semaphore = 1; 
        $readmonthname = $row[2];
        $readmonthname =~ s/`//g; 
        $readmonthnum = getmonthnum( $readmonthname ); 
      }
      if ( ( ( $row[0] eq "24" ) and ( $row[1] eq "hour" ) and ( $row[1] eq "surface" ) ) or ( $row[0] eq "*end" ) )
      {
        $semaphore = 0; 
      }

      my ( @newhourvals, @newhourvals2, @were );
      foreach my $monthnum ( sort {$a <=> $b} ( keys %{ $irrvars{ $zonenum } } ) )
      {  #say REPORT " %{ FROM MODIFYSHDA: FOREACH MONTHNUM: \$irrvars{ \$zonenum }{ \$monthnum } }; \$irrvars{ $zonenum }{ $monthnum } } : " . dump ( %{ $irrvars{ $zonenum }{ $monthnum } } ) . " keys %{ \$irrvars{ \$zonenum }{ \$monthnum } }; keys %{ \$irrvars{ $zonenum }{ $monthnum } } : " . dump ( keys %{ $irrvars{ $zonenum }{ $monthnum } } );
        my $monthname = getmonthname( $monthnum ); 
        push ( @monthnames, $monthname );
        push ( @monthnames2, $monthname );
        
        foreach my $surfnum ( sort {$a <=> $b} ( keys %{ $irrvars{ $zonenum }{ $monthnum } } ) )
        {  #say REPORT " %{ FROM MODIFYSHDA: FOREACH SURFNUM \$irrvars{ \$zonenum }{ \$monthnum }{ \$surfnum } }; \$irrvars{ $zonenum }{ $monthnum }{ $surfnum } } : " . dump ( %{ $irrvars{ $zonenum }{ $monthnum }{ $surfnum } } ) . " keys %{ \$irrvars{ \$zonenum }{ \$monthnum }{ \$surfnum } }; keys %{ \$irrvars{ $zonenum }{ $monthnum }{ $surfnum } } : " . dump ( keys %{ $irrvars{ $zonenum }{ $monthnum }{ $surfnum } } );
          my $surfname = $surfslist{$zonenum}{$surfnum}{surfname}; 
          foreach my $hour ( sort {$a <=> $b} ( keys %{ $irrvars{ $zonenum }{ $monthnum }{ $surfnum } } ) )
          {  #say REPORT " %{ FROM MODIFYSHDA: FOREACH HOUR \$irrvars{ \$zonenum }{ \$monthnum }{ \$surfnum }{ \$hour } }; \$irrvars{ $zonenum }{ $monthnum }{ $surfnum }{ $hour } } : " . dump ( %{ $irrvars{ $zonenum }{ $monthnum }{ $surfnum }{ $hour } } ) . " keys %{ \$irrvars{ \$zonenum }{ \$monthnum }{ \$surfnum }{ \$hour } }; keys %{ \$irrvars{ $zonenum }{ $monthnum }{ $surfnum }{ $hour } } : " . dump ( keys %{ $irrvars{ $zonenum }{ $monthnum }{ $surfnum }{ $hour } } );
            my $irrvariation = $irrvars{ $zonenum }{ $monthnum }{ $surfnum }{ $hour }{ irrvar }; 
            my $ambbase = $irrvars{ $zonenum }{ $monthnum }{ $surfnum }{ $hour }{ irramb }; ##say REPORT "\$ambbase\: " . dump($ambbase);
            if ( ( $zonenum ) and ( $monthnum ) and ( $hour ) and ( $surfnum ) and ( $irrvariation ) and ( $surfname ) and ( $monthname ) and ( $surfnum eq $elm ) ) # IF ALL THE NEEDED DATA EXIST
            {  #say REPORT "\$zonenum  $zonenum  \$monthnum  $monthnum  \$hour  $hour  \$surfnum  $surfnum  \$irrvariation  $irrvariation  \$surfname  $surfname  \$monthname  $monthname " ;
              if ( $semaphore == 1 )
              {
                if ( $row[27] eq "surface" )
                {
                  $readsurfname = $row[28]; 
                  $readsurfnum = $surfslist{$zonenum}{$readsurfname}{surfnum} ;
                  my @filledhourvals;
                  if ( ( $row[25] eq "diffuse" ) and ( $readsurfname eq $surfname ) )
                  {
                    my @hourvals = ( @row[ 0..23 ] ); 
                    my $counthour = 1;
                    foreach my $el ( @hourvals )
                    { # $el IS THE DIFFUSE SHADING FACTOR IN THE ORIGINAL SHDA FILE.
                      # %irrvariation IS THE IRRADIANCE DIFFERENCE BETWEEN THE "WHITE" MODEL AND THE "BLACK" MODEL.
                      # $ambase IS THE AMBIENT RADIATION WITHOUT SHADINGS
                      
                      my ( $calcamount, $improvedguess, $newshadingvalue);
                      if ( $irrvariation > 1 )
                      { 
                        $calcamount = ( 1 - $el ); # THIS IS THE RATIO OF NON-SHADED IRRADIATION AS CALCULATED BY THE ESP-r's ISH MODULE
                        $improvedguess = ( $calcamount * $irrvariation ); # THIS IS THE RATIO ABOVE CORRECTED BY MULTIPLYING IT BY THE IRRADIANCE RATIO TO TAKE REFLECTIONS INTO ACCOUNT.
                        $newshadingvalue = ( 1 - $improvedguess ); # AS THE NAME SAYS, THIS IS THE NEW SHADING VALUE.
                      }
                      else
                      {
                        $newshadingvalue = $el; # IF THE IRRADIANCE RATIO IS < 1 DON'T CHANCE THE ORIGINAL DIFFUSE SHADING FACTOR.
                      }
                      
                      if ( ( $counthour == $hour ) and ( $readmonthname eq $monthname ) and ( $readsurfnum == $surfnum ) ) # IT MEANS: IF THIS LINE IS THE RIGHT ONE...
                      {                  
  
                        if ( $newshadingvalue == 1 ) 
                        { 
                          $newshadingvalue = "1.0000"; 
                        }
                        if ( ( $newshadingvalue > 0 ) and ( $newshadingvalue < 1 ) ) # IF THE VARIATION OF IRRADIANCE FROM MODEL A AND MODEL B IS NEGATIVE...
                        {  # ...INCREASE THE SHADING FACTOR ACCORDINGLY. IMPORTANT NOTE: THIS IS A SIMPLIFICATION, 
                          # BECAUSE FOR BEST PRECISION THE WHOLE AMOUNT OF RADIATION ENTERING SHOULD BE REDUCED, NOT JUST THE DIFFUSE PART OF IT, 
                          # GOVERNED BY THE DIFFUSE SHADING FACTOR, AS IT IS BEING DONE HERE.
                          $newshadingvalue = sprintf ( "%.4f", $newshadingvalue ); # FORMAT THE NUMBER SO THAT IT HAS FOUR DECIMALS
                        }
                        if ( ( $newshadingvalue < 10 ) and ( $newshadingvalue < 0 ) )
                        {
                          $newshadingvalue = sprintf ( "%.3f", $newshadingvalue ); # IT THE NUMBER IS COMPRISED BETWEEN -10 AND = 0 FORMAT IT SO THAT IT HAS 3 DECIMALS
                        }
                        if ( ( $newshadingvalue < 100 ) and ( $newshadingvalue <= -10 ) )
                        {
                          $newshadingvalue = sprintf ( "%.2f", $newshadingvalue ); # IT THE NUMBER IS COMPRISED BETWEEN -100 AND = -10 FORMAT IT SO THAT IT HAS 2 DECIMALS
                        }
                        
                        #say REPORT "HERE IN MODIFISHDA value $el , due to \$newshadingvalue $newshadingvalue and \$irrvariation $irrvariation, in monthnum: $monthnum, monthname: $monthname, surfnum: $surfnum, hour: $hour " ;
                        say REPORT "OLD SHADING VALUE " . dump( $el );
                        say REPORT "NEW SHADING VALUE " . dump( $newshadingvalue );
                        my $irrvariation = sprintf ( "%.4f", $irrvariation ); say REPORT "SPRINTING $irrvariation!";
                        
                        #if ( not ( $newshadingvalue == 0 ) )
                        #{
                        #  if ( ( $el / $newshadingvalue ) <= ( $threshold ) )
                        # {
                        #   $newshadingvalue = $el; say REPORT "NEW SHADING VALUE " . dump( $newshadingvalue );
                        # }
                        #}
                        push ( @newhourvals, $newshadingvalue); #say REPORT "PUSHING $newshadingvalue! in newhourvals";
                        push ( @newhourvals2, $irrvariation );   #say REPORT "PUSHING $irrvariation! in newhourvals2";	
                        push ( @were, $el );
                      }	
                      $counthour++;
                    }
                    #@newhourvals = uniq( @newhourvals );
                    #@newhourvals2 = uniq( @newhourvals2 );
                    #@were = uniq( @were );
                    say REPORT "IN MODIFISHDA \@newhourvals (NEW SHADING VALUES) " . dump(@newhourvals) . ", in monthnum: $monthnum, monthname: $monthname, surfnum: $surfnum, hour: $hour";
                    say REPORT "IN MODIFISHDA \@newhourvals2 (IRRADIANCE RATIOS)" . dump(@newhourvals2) . ", in monthnum: $monthnum, monthname: $monthname, surfnum: $surfnum, hour: $hour";
                    say REPORT "IN MODIFISHDA OLD SHADING VALUES WERE : " . dump(@were) . ", in monthnum: $monthnum, monthname: $monthname, surfnum: $surfnum, hour: $hour";

                    my @filledhourvals = fillhours( \@newhourvals, $monthname, \%daylighthours ); #say REPORT "FOR MONTH $monthname, CALLING filledhourvals " . Dumper( @filledhourvals ); #say REPORT "\scalar(\@filledhourvals) " . scalar( @filledhourvals) ;

                    my @filledhourvals2 = fillhours( \@newhourvals2, $monthname, \%daylighthours ); #say REPORT "FOR MONTH $monthname, CALLING filledhourvals2 " . Dumper( @filledhourvals2 ); #say REPORT "\scalar(\@filledhourvals2) " . scalar( @filledhourvals2) ;
                      
                    if ( ( scalar ( @filledhourvals ) == 24 ) and ( $monthname eq $monthnames[0] ) )
                    {  
                      shift @monthnames;
                      my @firstarr = @filledhourvals[ 0..11 ]; 
                      my @secondarr = @filledhourvals[ 12..$#filledhourvals ]; 
                      my $joinedfirst = join ( ' ' , @firstarr ); 
                      my $joinedsecond = join ( ' ' , @secondarr ); 
                      my $newline = "$joinedfirst " . "$joinedsecond" . " # diffuse - surface " . "$readsurfname $monthname\n"; 
                      print TEMPMOD $newline;
                    }
                    
                    if ( ( scalar ( @filledhourvals2 ) == 24 ) and ( $monthname eq $monthnames2[0] ) )
                    {  
                      shift @monthnames2;
                      my @firstarr2 = @filledhourvals2[ 0..11 ]; 
                      my @secondarr2 = @filledhourvals2[ 12..$#filledhourvals2 ]; 
                      my $joinedfirst2 = join ( ' ' , @firstarr2 ); 
                      my $joinedsecond2 = join ( ' ' , @secondarr2 ); 
                      my $newline2 = "$joinedfirst2 " . "$joinedsecond2" . " # for surface " . "$readsurfname in $monthname\n"; 
                      print TEMPREPORT $newline2;
                    }                    
                  }
                }
              }
            }
            $countref++;
          } 
        } 
      }
    }    
  }  
}    


sub getbasevectors
{ # THIS GETS THE PRE-COMPUTED EVENTLY DISTRIBUTED N POINTS ON THE SURFACE OF A HEMISPHERE.
  my ( $dirvectorsnum ) = @_;
  my @basevectors;
  if ( $dirvectorsnum == 1 )
  {
    @basevectors = ( #[ 0, 0, 0 ] , # origin, base point of direction vector
        [ 0, 0, 1 ], # direction vector of high, central, vertical point
         ); # lowest vertices
  }
  if ( $dirvectorsnum == 5 )
  {
    @basevectors = ( #[ 0, 0, 0 ] , # origin, base point of direction vector
        [ 0, 0, 1 ], # direction vector of high, central, vertical point
        [ 1, 0, 0 ] , [ 0, 1, 0 ], [ -1, 0, 0 ], [ 0, -1, 0 ] ); # lowest vertices
  }
  elsif ( $dirvectorsnum == 9 )
  {
    @basevectors = ( #[ 0, 0, 0 ] , # origin, base point of direction vector
        [ 0, 0, 1 ], # direction vector of high, central, vertical point
        [ 0.7071, -0.7071, 0.4472 ] , [ 0.7071, 0.7071, 0.4472 ], [ -0.7071, 0.7071, 0.4472 ], [ -0.7071, -0.7071, 0.4472 ], # lower vectexes
        [ 1, 0, 0 ] , [ 0, 1, 0 ], [ -1, 0, 0 ], [ 0, -1, 0 ] ); # lowest vertices
  }
  return ( @basevectors );
}

sub createfictgeofile
{  # THIS MANAGES THE MODIFICATION OF THE FICTITIOUS GEO FILES FOR THE ZONE BY ADJUSTING THE OBSTRUCTION CONSTRUCTIONS TO FICTITIOUS EQUIVALENT
  my ( $geofile, $obsconstrsetref, $geofile_fict ) = @_; #say REPORT "\$geofile\: " . dump($geofile); #say REPORT "\$obsconstrsetref\: " . dump($obsconstrsetref); #say REPORT "\$geofile_fict\: " . dump($geofile_fict);
  my @obsconstrset = @$obsconstrsetref; 
  open ( GEOFILE, "$geofile" ) or die;
  my @lines = <GEOFILE>;
  close GEOFILE;
  
  open ( GEOFILE_FICT, ">$geofile_fict" ) or die;
  
  foreach my $line ( @lines )
  {
    if ( $line =~ /^\*obs/ )
    {
      foreach my $obsconstr ( @obsconstrset )
      {
        my $newobsconstr = $obsconstr; 
        $newobsconstr =~ s/\w\b// ;  
        $newobsconstr =~ s/\w\b// ; 
        $newobsconstr = "f_" . $newobsconstr; 
        $line =~ s/$obsconstr/$newobsconstr/; 
      }
      print GEOFILE_FICT $line;
    }
    else
    {
      print GEOFILE_FICT $line;  #say REPORT "\$line\: " . dump($line); 
    }
  }
  close ( GEOFILE_FICT);
}

sub creatematdbfiles
{  # THIS MANAGES THE CREATION OF THE TWO FICTITIOUS MATERIALS DATABASES.
  my ( $materialsref, $newmaterialsref, $matnumsref, 
  $newmatnumsref, $matdbfile, $matdbfile_fict1, $matdbfile_fict2 ) = @_; #say REPORT "\$materialsref\: " . dump($materialsref); 
  #say REPORT "\$newmaterialsref\: " . dump($newmaterialsref); #say REPORT "\$matnumsref\: " . dump($matnumsref);
  #say REPORT "\$newmatnumsref\: " . dump($newmatnumsref); #say REPORT "\$matdbfile\: " . dump($matdbfile);
  #say REPORT "\$matdbfile_fict1\: " . dump($matdbfile_fict1); #say REPORT "\$matdbfile_fict2\: " . dump($matdbfile_fict2);  
  my @materials = @$materialsref; 
  my @newmaterials = @$newmaterialsref; 
  my $newmattotnum = scalar( @newmaterials ); 
  my %matnums = %$matnumsref; 
  my %newmatnums = %$newmatnumsref; 
  
  open ( MATDBFILE, "$matdbfile" ) or die; 
  my @lines = <MATDBFILE>;
  close MATDBFILE;
  
  my @bag;
  foreach ( @lines )
  {
    $_ =~ /^\*item,(.+),(.+),(.+),(.+)$/ ; 
    push ( @bag, $2 );
  }
  my $mattotnum = max( @bag ); 
  
  my ( $classnum, $newclassnum, $newclasstotnum );
  
  my ( @firstloop, @copy );
  my $countline = 0;
  foreach my $line ( @lines )
  {
    if ( $line =~ /# number of classifications/ )
    {
      my @row = split( /\s+|,/ , $line );
      my $classtotnum = $row[0]; 
      $newclasstotnum = ( $classtotnum + 1 ); 
      $line =~ s/$classtotnum/$newclasstotnum/; 
      my $extractvalue = $line; 
      $line = $extractvalue;
    }

    if ( $line =~ /\*item/ )
    {
      my @row = split( /,/ , $line );
      my $item = $row[1]; 
      if ( $item ~~ @materials )
      {
        my $newitem = $item;
        $newitem =~ s/\w\b// ;
        $newitem =~ s/\w\b// ;
        $newitem = "f_" . $newitem; 
        my $newline = $line;
        $newline =~ s/$item/$newitem/; 
        my $afterline = $lines[ $countline + 1 ]; 
        push ( @copy, [ $newline, $afterline ] ); 
      } #say REPORT "\@copy\: " . dump(@copy);
    }
    push ( @firstloop, $line ); #say REPORT "\@firstloop\: " . dump(@firstloop);
    $countline++;
  }
  pop ( @firstloop ); 
  
  my @newcopy;
  my %exportrefl;
  my $newmatstotnum = scalar ( @copy );
  push ( @newcopy, "*class,$newclasstotnum, $newmatstotnum,Fictitious\n" );
  push ( @newcopy, "Category ($newclasstotnum) holds fictitious materials for shading and insolation calculations\n" );
  my $countnew = 1;
  foreach ( @copy )
  {
    my $counttwo = 1;
    my ( $namematobs, $absout, $absin );
    my @box;
    foreach ( @$_ )
    {
      if ( $counttwo == 1 )
      {
        my $newmattotnum = ( $mattotnum + $countnew ); 
        $_ =~ /^\*item,(.+),(.+),(.+),(.+)$/ ; 
        $namematobs = $1; 
        $_ = "*item,$1, $newmattotnum, $countnew,$4\n"; 
      }
      $_ =~ s/\s//;
      $_ =~ s/\s//;
      if ( $counttwo == 2 )
      {        
        $_ =~ /(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),-/ ;
        $absout = $6; 
        $absin = $7; 
      }
      push ( @newcopy, $_ );
      $exportrefl{ $namematobs }{ absout } =  $absout;
      $exportrefl{ $namematobs }{ absin } = $absin;
      $counttwo++;
    }
    $countnew++;
  } #say REPORT "\@newcopy\: " . dump(@newcopy);
  
  my @blackcopy;
  my @tempcopy = @newcopy;
  foreach my $line ( @tempcopy )
  {
    if ( $line =~ /(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),-/ )
    {
      my $absout = "0.990";
      my $absin = "0.990";
      $line = "$1,$2,$3,$4,$5,$absout,$absin,$8,$9,-\n";
    }
    push ( @blackcopy, $line );
  } #say REPORT "\@blackcopy\: " . dump(@blackcopy);
  
  my @blackloop;
  my @secondtemploop = @firstloop;
  foreach ( @secondtemploop )
  {
    if ( $_ =~ /(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),-/ )
    {
      my $absout = "0.990";
      my $absin = "0.990";
      $_ = "$1,$2,$3,$4,$5,$absout,$absin,$8,$9,-\n";
    }
    push ( @blackloop, $_ );
  }   #say REPORT "\@secondtemploop\: " . dump(@secondtemploop);
  
  my @whiteloop = @blackloop;
  push ( @blackloop, @blackcopy, "*end\n" );   
  push ( @whiteloop, @newcopy, "\n*end\n" );   
  
  open (MATDBFILE_FICT1, ">$matdbfile_fict1" ) or die;
  foreach ( @blackloop )
  {
    print MATDBFILE_FICT1 $_;
  }
  close MATDBFILE_FICT1;
  
  open (MATDBFILE_FICT2, ">$matdbfile_fict2" ) or die;
  foreach ( @whiteloop )
  {
    print MATDBFILE_FICT2 $_;
  }
  close MATDBFILE_FICT2; #say REPORT "\%exportrefl\: " . dump(%exportrefl);
  return ( \%exportrefl );
}

sub adjust_radmatfile
{ # THIS CHECKS IF THE RADIANCE MATERIAL FILE HAS BEEN PROPERLY MODIFIED. IF NOT, IT DOES THE MODIFICATION BY ITSELF.
  my ( $exportconstrref, $exportreflref, $conffile, $path ) = @_; 
  say REPORT "IN ADJUST_RADMATFILE: \$exportconstrref\: " . dump($exportconstrref); say REPORT "\$exportreflref\: " . dump($exportreflref);
  say REPORT "\$conffile\: " . dump($conffile); say REPORT "\$path\: " . dump($path);
  my %exportconstr = %$exportconstrref; 
  my %exportrefl = %$exportreflref; 
  my $radmat_fict2 = $conffile; 
  $radmat_fict2 =~ s/$path\/cfg\///;
  $radmat_fict2 =~ s/.cfg//;
  $radmat_fict2 = $radmat_fict2 . "_Extern.mat";
  $radmat_fict2 = "$path/rad/$radmat_fict2"; 
  my $radmattemp = $radmat_fict2 . ".temp"; 
  `mv -f $radmat_fict2 $radmattemp`;
  open( RADMATTEMP, "$radmattemp" ) or die;
  my @lines = <RADMATTEMP>;
  close RADMATTEMP;
  open( RADMAT_FICT2, ">$radmat_fict2" ) or die;
  my $count = 0;
  my @constrs = keys %exportconstr;  say REPORT "\@constrs\: " . dump(@constrs);
  foreach ( @lines )
  {
    if ( $_ =~ /# External MLC Colours.../ )
    {
      foreach ( @constrs )
      {
        my $constrout = "rc_ex_" . $_; 
        if ( $lines[ $count + 1] =~ /$constrout/ )
        {
          my $extmat = $exportconstr{ $_ }{ extlayer }; 
          my $absextext = $exportrefl{ $extmat }{ absout }; 
          my $refl = 1 - $absextext; say REPORT "\$refl EXT\ " . dump( $refl );
          $refl = sprintf( "%.2f", $refl ); say REPORT "\$refl\ " . dump( $refl );
          $lines[ $count + 4 ] =~ /5  (\d+) (\d+) (\d+) (\d+) (\d+)/ ;
          $lines[ $count + 4 ] = "5  $refl $refl $refl 0 0\n"; 
        }
      }
    }
    if ( $_ =~ /# Internal MLC Colours.../ )
    {
      foreach ( @constrs )
      {
        my $constrin = "rc_in_" . $_;
        if ( $lines[ $count + 1] =~ /$constrin/ )
        {
          my $intmat = $exportconstr{ $_ }{ intlayer }; 
          my $absintint = $exportrefl{ $intmat }{ absin }; 
          my $refl = 1 - $absintint; say REPORT "\$refl INT\ " . dump( $refl );
          $refl = sprintf( "%.2f", $refl );  say REPORT "\$refl INT\ " . dump( $refl );
          $lines[ $count + 4 ] =~ /5  (\d+) (\d+) (\d+) (\d+) (\d+)/ ;
          $lines[ $count + 4 ] = "5  $refl $refl $refl 0 0\n"; 
        }
      }
    }
    print RADMAT_FICT2 $lines[ $count ]; #say REPORT "\$lines[ \$count ]\ " . dump( $lines[ $count ] );
    $count++;
  }
  close RADMAT_FICT2;
}

sub calcdirvectors
{ # THIS CALCULATES THE NEEDED DIRECTION VECTORS AT EACH GRID POINT.
  my @winscoords = @_; 
  my ( @groupbag );
  foreach my $surf ( @winscoords )
  {
    my ( @surfbag );
    foreach my $v ( @$surf )
    {
      my @fields = @$v; 
      my $coordsref = $fields[0]; 
      my @coords = @$coordsref;
      my $vertex = Vector::Object3D::Point->new( x => $coords[0], y => $coords[1], z => $coords[2] ); 
      push ( @surfbag, $vertex); 
    }

    my $polygon = Vector::Object3D::Polygon->new(vertices => [ @surfbag ]); 
    my $normal_vector = $polygon->get_normal_vector; 
    my ($x_, $y_, $z_) = $normal_vector->array; 
    my ( $x, $y, $z ) = ( -$x_, -$y_, -$z_ ); 
    my $max = max( abs($x), abs($y), abs($z) ); 
    my @dirvector;
    unless ( $max == 0 )
    {
      $x = ( $x / $max );
      $y = ( $y / $max );
      $z = ( $z / $max );
      @dirvector =  ( $x, $y, $z );
    }
    else 
    {
      @dirvector =  ( $x, $y, $z );
    }
    push ( @groupbag, [ @dirvector ] )
  }
  return ( @groupbag);
}

sub prunepoints
{ # IT PRUNES AWAY GRID POINTS FALLING OUTSIDE OF THE SURFACE.
  my ( $gridpoints_transitionalref, $xyzcoordsref ) = @_;
  my @gridpoints = @$gridpoints_transitionalref; 
  my @vertstaken = @$xyzcoordsref; 
  
  my @verts;
  foreach ( @vertstaken )
  {
    my @fields = @$_; 
    my @xs = @{ $fields[0] }; 
    my @ys = @{ $fields[1] }; 
    my @zs = @{ $fields[2] }; 
    my $i = 0;
    my @bag;
    foreach ( @xs )
    {
      push ( @bag, [ $xs[ $i ], $ys[ $i ], $zs[ $i ] ] );
      $i++;
    }
    push ( @verts, [ @bag ] );
  } 
  
  my ( @coords, @prunegridpoints );

  foreach my $v ( @gridpoints )
  {
    my @fields = @$v; 
    my $coordsref = $fields[0]; 
    push( @coords, [ @$coordsref ] );
  } 
  
  
  my ( @boxpointxy, @boxpointxz, @boxpointyz );
  foreach my $gridpoint ( @coords )
  {
    my ( @point_xys, @point_xzs, @point_yzs );
    foreach ( @$gridpoint )
    {
      push ( @point_xys, [ $_->[0], $_->[1] ] );
      push ( @point_xzs, [ $_->[0], $_->[2] ] );
      push ( @point_yzs, [ $_->[1], $_->[2] ] );
    }
    push ( @boxpointxy, [ @point_xys ] );
    push ( @boxpointxz, [ @point_xzs ] );
    push ( @boxpointyz, [ @point_yzs ] );
  } 
  
  my ( @boxvertxy, @boxvertxz, @boxvertyz );
  foreach my $surf ( @verts )
  {
    my ( @vert_xys, @vert_xzs, @vert_yzs );
    foreach my $vert ( @$surf )
    {
      push ( @vert_xys, [ $vert->[0], $vert->[1] ] );
      push ( @vert_xzs, [ $vert->[0], $vert->[2] ] );
      push ( @vert_yzs, [ $vert->[1], $vert->[2] ] );
    }
    push ( @boxvertxy, [ @vert_xys ] );
    push ( @boxvertxz, [ @vert_xzs ] );
    push ( @boxvertyz, [ @vert_yzs ] );
  } 
  
  my $count = 0;
  my ( $vert_xys, $vert_xzs, $vert_yzs, $polyxy, $polyxz, $polyyz );
  my ( @verts_xys, @verts_xzs, @verts_yzs);
  foreach my $case ( @boxvertxy )
  {
    $vert_xys = $boxvertxy[$count]; 
    $vert_xzs = $boxvertxz[$count]; 
    $vert_yzs = $boxvertyz[$count]; 
    $polyxy = Math::Polygon::Tree->new( $vert_xys ); 
    $polyxz = Math::Polygon::Tree->new( $vert_xzs ); 
    $polyyz = Math::Polygon::Tree->new( $vert_yzs ); 
    $count++;
  }
  
  my $count = 0;
  my @newbox;
  foreach my $caseref ( @gridpoints )
  {
    my @case = @$caseref; 
    my $surfnum = $case[ 1 ];
    my $dirvector = $case[ 2 ];
    my @bag;
    foreach my $vert ( @{ $case[ 0 ] } )
    
    {  
      my $xyref = $boxpointxy[ $count ][ 0 ]; 
      my $xzref = $boxpointxz[ $count ][ 0 ]; 
      my $yzref = $boxpointyz[ $count ][ 0 ]; 
      unless ( ( ( $polyxy->contains( $xyref ) ) == 0 ) and ( ( $polyxz->contains( $xzref ) ) == 0 ) and ( ( $polyyz->contains( $yzref ) ) == 0 ) )
      {
        push( @bag, $vert ); 
      }
    } 
    push ( @newbox, [ [ @bag ], $surfnum, $dirvector ] );
    $count++;
  } 
  return ( @newbox );
}


sub modish
{ # MAIN PROGRAM
  my $launchfile = shift;
  my @restpars = @_; #REMAINING PARAMETERS GIVEN TO THE SHELL
  my ( $conffile, $path, $zonenum, $dirvectorsnum, $bounceambnum, $bouncemaxnum, $distgrid, $threshold );
  my ( @transpdata, @surfaces, @dirvectorsrefs, @transpsurfs, @resolutions, @treatedlines );
  
  say "Setting things up...\n";
  
  if ( scalar( @restpars ) == 0 ) 
  {   # IF modish.pl IS CALLED THROUGH A CONFIGURATION FILE...
    require $launchfile; 
    $conffile = $launchdata[0]; 
    $path = definepath($conffile); 
    $zonenum = $launchdata[1]; 
    @transpsurfs = @launchdata[ 2..$#launchdata ];
  }
  else 
  {  # IF modish.pl IS CALLED ENTIRELY THROUGH THE COMMAND LINE, ASSUME THOSE DEFAULTS...
    $conffile = $launchfile; 
    $path = definepath($conffile); 
    $zonenum = shift( @restpars ); 
    @transpsurfs = @restpars; 
  }
  #say "TRANSPSURFS: " . dump( @transpsurfs );
  if ( -e "./modish_defaults.pl" )
  { 
    require "./modish_defaults.pl";
  }
  @resolutions = @{ $defaults[0] };
  $dirvectorsnum = $defaults[1];
  $bounceambnum = $defaults[2];
  $bouncemaxnum = $defaults[3];
  $distgrid = $defaults[4];
  $threshold = $defaults[5];
  # say "PATH: " . $path;
  open ( REPORT, ">$path/writefile.txt" ) or die;
  say REPORT "I'M OPEN";
  #open ( REPORT2, ">$path/report2.txt" ) or die;
    
  if ( not ( @resolutions ) ) { @resolutions = ( 2, 2 ); };
  @resolutions = ( $resolutions[0], @resolutions ); 
  if ( not defined( $dirvectorsnum ) ) { $dirvectorsnum = 1; };  
  if ( not defined( $bounceambnum ) ) { $bounceambnum = 1; }; 
  if ( not defined( $bouncemaxnum ) ) { $bouncemaxnum = 7; };
  if ( not defined( $distgrid ) ) { $distgrid = 0.01; };
  if ( not defined( $threshold ) ) { $threshold = 0.99; };
  #say "OBTAINED DEFAULTS: ";
  #say REPORT "\@resolutions\ " . dump( @resolutions );
  #say REPORT "\$resolutions[0]\ " . dump( $resolutions[0] );
  #say REPORT "\$dirvectorsnum\ " . dump( $dirvectorsnum );
  #say REPORT "\$bounceambnum\ " . dump( $bounceambnum );
  #say REPORT "\$bouncemaxnum\ " . dump( $bouncemaxnum );
  #say REPORT "\$distgrid\ " . dump( $distgrid );
  #say REPORT "\$threshold\ " . dump( $threshold );

  my ($conffile, $conffile_fict1, $conffile_fict2, $conffile_fict3, $constrdbfile, $constrdbfile_fict,
  $matdbfile, $matdbfile_fict1, $matdbfile_fict2, $flagconstrdb, $flagmatdb, $flaggeo, $flagconstr, $originalsref, 
  $fictitia1ref, $fictitia2ref, $fictitia3ref ) = createfictitiousfiles( $conffile, $path, $zonenum );   
  
  my @basevectors = getbasevectors( $dirvectorsnum );
      
  my @originals = @$originalsref; #say REPORT "\@originals\ " . dump( @originals );
  my @fictitia1 = @$fictitia1ref; #say REPORT "\@fictitia1\ " . dump( @fictitia1 );
  my @fictitia2 = @$fictitia2ref;  #say REPORT "\@fictitia2\ " . dump( @fictitia2 );
  my @fictitia3 = @$fictitia3ref; #say REPORT "\@fictitia3\ " . dump( @fictitia3 );
  
  my ( @actiondata, @daylighthours);
  my @zoneoriginals = @originals; 
  shift(@zoneoriginals); shift(@zoneoriginals);
  my @zonefictitia1 = @fictitia1; # "BLACK" MODEL
  shift(@zonefictitia1); shift(@zonefictitia1);
  my @zonefictitia2 = @fictitia2; # "WHITE" MODEL
  shift(@zonefictitia2); shift(@zonefictitia2);
  my @zonefictitia3 = @fictitia3; 
  shift(@zonefictitia3); shift(@zonefictitia3);
  
  my ( %zonefilelists, %fict1filelists, %fict2filelists, %fict3filelists );
  my @daylighthoursarr;
  my %daylighthours;
  my ( $exportreflref__, $exportconstrref__ );
  
  my  $tempmod = "$conffile.mod.temp"; #say "TEMPMOD1: " . dump($tempmod); 
  if ( $^O eq "linux" ) # THESE LINES DEPEND FROM THE OPERATING SYSTEM
  {
    $tempmod =~ s/$path\/cfg\///; #say "TEMPMOD2: " . dump($tempmod); say "PATH " . dump($path);
    $tempmod = "$path/tmp/$tempmod"; #say "TEMPMOD3: " . dump($tempmod); 
    unless ( -e "$path/tmp" )
    {
      `mkdir $path/tmp`;
      say REPORT "mkdir $path/tmp";
    }
  }
  elsif ( $^O eq "darwin" )
  { ; }
  
  say REPORT "\$tempmod $tempmod";
  open ( TEMPMOD, ">$tempmod" ) or die;
  
  my $tempreport = "$conffile.report.temp";
  if ( $^O eq "linux" ) # THESE LINES DEPEND FROM THE OPERATING SYSTEM
  {
    $tempreport =~ s/$path\/cfg\///;
    $tempreport = "$path/tmp/$tempreport"; 
  }
  elsif ( $^O eq "darwin" )
  { ; }
  open ( TEMPREPORT, ">$tempreport" ) or die;
  
  `cp -f ./fix.sh $path/rad/fix.sh`;
  say REPORT "cp -f ./fix.sh $path/rad/fix.sh\n";
  `chmod 755 $path/rad/fix.sh`;
  `chmod 755 ./fix.sh`;
  say REPORT "chmod 755 $path/rad/fix.sh\n";
  `cp -f ./perlfix.pl $path/rad/perlfix.pl`;
  say REPORT "cp -f ./perlfix.pl $path/rad/perlfix.pl\n";

  my $countzone = 1;
  foreach my $elt (@zoneoriginals)
  {
    my @zonefiles = @$elt; #say REPORT "\@zonefiles " . dump( @zonefiles ); 
    my @fict1files = @{ $zonefictitia1[ $countzone - 1 ] }; # say REPORT "\@fict1files " . dump( @fict1files ); 
    my @fict2files = @{ $zonefictitia2[ $countzone - 1 ] }; # say REPORT "\@fict2files " . dump( @fict2files ); 
    my @fict3files = @{ $zonefictitia3[ $countzone - 1 ] }; # say REPORT "\@fict3files " . dump( @fict3files ); 
    my $geofile = $zonefiles[0]; # say REPORT "\$geofile " . dump( $geofile ); 
    my $constrfile = $zonefiles[1]; # say REPORT "\$constrfile " . dump( $constrfile ); 
    my $shdfile = $zonefiles[2]; # say REPORT "\$shdfile " . dump( $shdfile ); 
    my $zonenum_cfg = $zonefiles[3]; #say REPORT "\$zonenum_cfg " . dump( $zonenum_cfg ); 
    my $geofile_fict = $fict1files[0]; #say REPORT "\$geofile_fict " . dump( $geofile_fict ); 
    my $constrfile_fict = $fict1files[1]; #say REPORT "\$constrfile_fict " . dump( $constrfile_fict ); 
    $zonefilelists{ $zonenum }{ geofile } = $geofile;
    $zonefilelists{ $zonenum }{ geofile_fict } = $geofile_fict;
    $zonefilelists{ $zonenum }{ constrfile } = $constrfile;
    $zonefilelists{ $zonenum }{ constrfile_fict } = $constrfile_fict;
    $zonefilelists{ $zonenum }{ shdfile } = $shdfile;
    

    my ( $transpeltsref, $geofilestructref, $surfslistref, $obsref, $obsconstrsetref, $datalistref ) = readgeofile( $geofile, \@transpsurfs, $zonenum ); #HEREZZZ
    
    my @transpelts = @$transpeltsref; 
    my @geodata = @$geofilestructref;   
    my %surfslist = %$surfslistref; 
    my @obsdata = @$obsref; 
    my @obsconstrset = @$obsconstrsetref; 
    my %datalist = %$datalistref;
    
    createfictgeofile( $geofile, \@obsconstrset, $geofile_fict );

    my ( $materialsref, $newmaterialsref, $matnumsref, $newmatnumsref, $exportconstrref ) = 
    createconstrdbfile( $constrdbfile, $constrdbfile_fict, \@obsconstrset ); 

    $exportconstrref__ = $exportconstrref;
    
    my $exportreflref = creatematdbfiles( $materialsref, $newmaterialsref, $matnumsref, $newmatnumsref, 
    $matdbfile, $matdbfile_fict1, $matdbfile_fict2 ); 
    $exportreflref__ = $exportreflref;    


    my ( $surfnumsref, $surfnamesref ) = tellsurfnames( \@transpsurfs, \@geodata ); 
    my @surfnums = @$surfnumsref; 
    my @surfnames = @$surfnamesref; 
    my ( $winseltsref, $datalistref ) = readverts( \@transpelts, $geofile, \@geodata, \%datalist ); 
    my @winselts = @$winseltsref; 
    my %datalist = %$datalistref; 
    my ( $winscoordsref, $datalistref ) = readcoords( \@winselts, $geofile, \@geodata, \%datalist, \@transpelts ); 
    my @winscoords = @$winscoordsref; 
    my %datalist = %$datalistref; 
    my @dirvectorsrefs = calcdirvectors( @winscoords ); 
    my @xyzcoords = getcorners( \@winscoords, \@winselts ); 
    my @extremes = findextremes( @xyzcoords ); 
    my @gridcoords = makecoordsgrid( \@extremes, \@resolutions, \@dirvectorsrefs ); 
    my @gridpoints_transitional = makegrid( @gridcoords ); 
    my @gridpoints_newtransitional = prunepoints( \@gridpoints_transitional, \@xyzcoords ); 
    my @gridpoints = adjustgrid( \@gridpoints_newtransitional, $distgrid ); 
    #say REPORT "\"shdfile : " . dump( $shdfile );
    my ( $treatedlinesref, $filearrayref, $monthsref ) = readshdfile( $shdfile ); 
    @treatedlines = @$treatedlinesref;
    my @shdfilearray = @$filearrayref; #say REPORT "\@shdfilearray\ " . dump( @shdfilearray );
    my @months = @$monthsref; #say REPORT "\@months\ " . dump( @months );
    my @shdsurfdata = getsurfshd( \@shdfilearray, \@months, \@surfnums, \@surfnames ); #say REPORT "\@shdsurfdata\ " . dump( @shdsurfdata );
    @daylighthoursarr = checklight( \@shdfilearray, \@months );     say REPORT "\@daylighthoursarr\ " . dump( @daylighthoursarr );
    %daylighthours = populatelight( @daylighthoursarr ); say REPORT "\%daylighthours\ " . dump( %daylighthours );
    push ( @actiondata, [ [ $zonenum, $geofile, $constrfile, $shdfile ], [ @gridpoints ], [ @shdsurfdata ], [ @daylighthoursarr ], [ @shdfilearray ] ] ); 
    $shdfileslist{ $zonenum } = \@treatedlines; 
    $countzone++;
    
    
    my @radfilesrefs = tellradfilenames( $path, $conffile_fict1, $conffile_fict2, $conffile_fict3 ); #say REPORT "\@radfilesrefs\ " . dump( @radfilesrefs );
    unshift( @actiondata, $path, @radfilesrefs, $bounceambnum, $bouncemaxnum ); #say REPORT "\@actiondata\ " . dump( @actiondata );
    my ( $hashirrsref ) = pursue( $exportconstrref__, $exportreflref__, $conffile, \@basevectors, @actiondata ); #say REPORT "\$hashirrsref\ " . dump( $hashirrsref );
    my ( $irrvarsref ) = compareirrs( \%zonefilelists, $hashirrsref );         #say REPORT "\$irrvarsref\ " . dump( $irrvarsref );
    
    foreach my $elm ( @transpsurfs )
    {
      my @transpsurfs;
      push ( @transpsurfs, $elm );
      say "Closing calculations for surface " . dump( @transpsurfs ); 
        
        
      modifyshda( \@comparedirrs, \%surfslist, \%zonefilelists, \%shdfileslist, \%daylighthours, $irrvarsref, $threshold, $tempmod, $tempreport, $elm );
        

    }
  
  
  }
  
  close TEMPMOD;
  open ( TEMPMOD, "$tempmod" ) or die;
  my @tempmodlines = <TEMPMOD>;
  close TEMPMOD;
  @tempmodlines = uniq( @tempmodlines );
  
  close TEMPREPORT;
  open (TEMPREPORT, "$tempreport" ) or die;
  my @tempreportlines = <TEMPREPORT>;
  close TEMPREPORT;
  @tempreportlines = uniq( @tempreportlines );

  
  
  my $shdfile = $zonefilelists{ $zonenum }{ shdfile }; #say REPORT "\$shdfile\: " . dump($shdfile);
  my $shdafile = "$shdfile" . "a";  #say  "\$shdafile\: " . dump($shdafile);
  my $shdafilemod = $shdafile;
  $shdafilemod =~ s/.shda/.mod.shda/;
  open ( SHDAMOD, ">$shdafilemod" ) or die; #say REPORT "I OPEN $shdafilemod";
  
  my $shdafilereport = $shdafile;
  $shdafilereport =~ s/.shda/.report.shda/; #say  "\$shdafilereport\: " . dump($shdafilereport);
  `cp -R -f $shdafile $shdafilereport`; 
  open ( SHDAREPORT, ">>$shdafilereport" ) or die;
  print SHDAREPORT "# FOLLOWING, THE VERIFIED VARIATIONS (AS RATIOS) OF IRRADIANCES DUE TO REFLECTIONS BY OBSTRUCTIONS.\n";
  
  foreach my $lin ( @tempreportlines )
  {
    print SHDAREPORT $lin;
  }
  close SHDAREPORT;
  
  #say "GOT \@treatedlines: " . dump( @treatedlines );
  my @container;
  my ($currentmonth, $signal);
  foreach my $lin ( @treatedlines )
  {
    my @arr = split(/\s+|,/, $lin); 
    if ( $lin =~ /^\* month:/ )
    { #say "ARR: " . dump( @arr );
      $currentmonth = $arr[2]; #say "CURRENTMONTH: $currentmonth" ;
      $currentmonth =~ s/`//g; #say "CURRENTMONTH: $currentmonth" ;
    }
    if ( $lin =~ /^24 hour external surface shading/ )
    {
      $signal = "on";
    }
    elsif ( ( $lin =~ /^24 hour internal surface insolation/ ) or ( /\* month:/ ) )
    {
      $signal = "off";
    }
    my $count = 0;
    foreach my $el ( @tempmodlines )
    {
      my @modarr = split( /\s+|,/, $el );
      if ( $signal eq "on" )
      {
        push( @arr, $currentmonth );
        if ( ( $arr[25] eq $modarr[25] ) and ( $arr[28] eq $modarr[28] ) and ( $arr[29] eq $modarr[29] ) )
        {
          $el =~ s/ $currentmonth?//;
          push( @container, $el );
          $count++;
          last;
        }
      }
    }
    if ( $count == 0 )
    {
      push( @container, $lin );
    }
  }
  
  foreach my $lin ( @container )
  {
    if ( ( $lin =~ / # diffuse - / ) or ( $lin =~ / # direct - / ) )
    {
      my  @arr = split(/\s+|,/, $lin);
      my @firstarr = @arr[ 0..11 ]; 
      my @secondarr = @arr[ 12..$#arr ]; 
      my $joinedfirst = join ( ' ' , @firstarr ); 
      my $joinedsecond = join ( ' ' , @secondarr ); 
      $lin = "$joinedfirst\n" . "$joinedsecond\n";
    }
    print SHDAMOD $lin;
  }
  close SHDAMOD;
}

modish( @ARGV );

1;


