Skip to content
58 changes: 48 additions & 10 deletions Cell2Fire/Cell2Fire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ std::unordered_map<int, std::vector<int>> HarvestedCells;
std::vector<int> NFTypesCells;
std::unordered_map<int, int> IgnitionHistory;
std::unordered_map<int, std::string> WeatherHistory;
std::unordered_map<int, std::vector<float>> Statistics;
std::unordered_map<int, float> meanSurfaceFlameLength;
std::unordered_map<int, float> meanCrownFlameLength;
std::unordered_map<int, float> meanMaxFlameLength;

/******************************************************************************
Utils
Expand Down Expand Up @@ -176,9 +180,6 @@ Cell2Fire::Cell2Fire(arguments _args) : CSVForest(_args.InFolder + "fuels", " ")
this->args = _args;
this->args_ptr = &this->args;

// this->wdf_ptr = new weatherDF;
// this->wdf[100000];

/********************************************************************
*
* Initialization
Expand Down Expand Up @@ -341,7 +342,6 @@ Cell2Fire::Cell2Fire(arguments _args) : CSVForest(_args.InFolder + "fuels", " ")
this->harvestCells.insert(i + 1);
}

// POTENCIALMENTE AQUI ESTA MALO
/* Weather DataFrame */
// this->WeatherData = this->CSVWeather.getData();
// std::cout << "\nWeather DataFrame from instance " << this->CSVWeather.fileName << std::endl;
Expand Down Expand Up @@ -673,7 +673,7 @@ Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1)
this->surfaceIntensityFolder = Cell2Fire::createOutputFolder("SurfaceIntensity");
}
// Crown Byram Intensity Folder
if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator == "S"))
if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator != "C"))
{
this->crownIntensityFolder = Cell2Fire::createOutputFolder("CrownIntensity");
}
Expand All @@ -683,15 +683,19 @@ Cell2Fire::reset(int rnumber, double rnumber2, int simExt = 1)
this->surfaceFlameLengthFolder = Cell2Fire::createOutputFolder("SurfaceFlameLength");
}
// Crown Flame Length Folder
if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S"))
if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C"))
{
this->crownFlameLengthFolder = Cell2Fire::createOutputFolder("CrownFlameLength");
}
// max Flame Length Folder
if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S"))
if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C"))
{
this->maxFlameLengthFolder = Cell2Fire::createOutputFolder("MaxFlameLength");
}
if (this->args.Stats)
{
this->statsFolder = Cell2Fire::createOutputFolder("Statistics");
}
// Crown Folder
if (this->args.OutCrown && this->args.AllowCROS)
{
Expand Down Expand Up @@ -1749,7 +1753,7 @@ Cell2Fire::Results()
}

// Crown Intensity
if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator == "S"))
if ((this->args.OutIntensity) && (this->args.AllowCROS) && (this->args.Simulator != "C"))
{
this->crownIntensityFolder = this->args.OutFolder + "CrownIntensity" + separator();
std::string intensityName;
Expand Down Expand Up @@ -1785,7 +1789,7 @@ Cell2Fire::Results()
}

// Crown Flame length
if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S"))
if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C"))
{
this->crownFlameLengthFolder = this->args.OutFolder + "CrownFlameLength" + separator();
std::string fileName;
Expand All @@ -1803,7 +1807,7 @@ Cell2Fire::Results()
}

// Max Flame length
if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator == "S"))
if ((this->args.OutFl) && (this->args.AllowCROS) && (this->args.Simulator != "C"))
{
this->maxFlameLengthFolder = this->args.OutFolder + "MaxFlameLength" + separator();
std::string fileName;
Expand All @@ -1820,6 +1824,40 @@ Cell2Fire::Results()
this->rows, this->cols, this->xllcorner, this->yllcorner, this->cellSide, this->maxFlameLengths);
}

// Flame Length Statistics
// This will be used to store accumulated flame lengths across simulations
if (this->args.Stats)
{

for (int cell : this->burntCells)
{
std::vector<float> flameLengthMeans;

float surfaceFlameLength = this->surfaceFlameLengths[cell] / args.TotalSims;
meanSurfaceFlameLength[cell] += surfaceFlameLength;
flameLengthMeans.push_back(meanSurfaceFlameLength[cell]);

if ((this->args.AllowCROS) && (this->args.Simulator != "C"))
{
float crownFlameLength = this->crownFlameLengths[cell] / args.TotalSims;
float maxFlameLength = this->maxFlameLengths[cell] / args.TotalSims;
meanCrownFlameLength[cell] += crownFlameLength;
meanMaxFlameLength[cell] += maxFlameLength;
flameLengthMeans.push_back(meanCrownFlameLength[cell]);
flameLengthMeans.push_back(meanMaxFlameLength[cell]);
}

Statistics[cell] = { flameLengthMeans };
}
if (currentSim == args.TotalSims)
{
std::ostringstream oss;
std::string Statsname = this->statsFolder + "statistics" + oss.str() + ".csv";
CSVWriter statsFile(Statsname);
statsFile.printStats(Statistics);
}
}

// Intensity
if ((this->args.OutCrownConsumption) && (this->args.AllowCROS))
{
Expand Down
1 change: 1 addition & 0 deletions Cell2Fire/Cell2Fire.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class Cell2Fire
string crownFlameLengthFolder;
string historyFolder;
string ignitionsFolder;
string statsFolder;

// Vectors
std::vector<int> fire_period;
Expand Down
2 changes: 1 addition & 1 deletion Cell2Fire/Cells.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ Cells::manageFire(int period,
surfFraction[nb] = metrics.sfc;
SurfaceFlameLengths[this->realId - 1] = mainstruct.fl;
SurfaceFlameLengths[nb - 1] = metrics.fl;
if ((args->AllowCROS) && (args->Simulator == "S"))
if ((args->AllowCROS) && (args->Simulator != "C"))
{
float comp_zero = 0;
MaxFlameLengths[this->realId - 1]
Expand Down
51 changes: 51 additions & 0 deletions Cell2Fire/FuelModelKitral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,51 @@ byram_intensity(inputs* data, main_outs* at)
return ib; // unidad de medida
}

/**
* Calculates byram fire intensity when there is active crown fire.
* In order for this to be calculated, the input folder must contain
* files with CBD, CBH and tree height data for each cell.
* @param at Structure containing the cell's output data.
* @param data Structure containing the cell's input data.
* @return Fire intensity.
*/

float
crown_byram_intensity_k(main_outs* at, inputs* data)
{
float cbd, cbh;
cbd = data->cbd;
cbh = data->cbh;
// CBH is 0,1012 * Height^(1,4822)
float canopy_height = std::pow(cbh / 0.1012, 1 / 1.4822) - cbh;
if (canopy_height < 0)
{
throw std::runtime_error("Tree height is lower than canopy base height, "
"please provide valid files.");
}
return std::ceil((hs[data->nftype][0] / 60) * cbd * canopy_height * at->ros_active * 100.0) / 100.0;
}

/**
* @brief Calculates the flame length of a cell when there is crown fire.
* @param intensity Byram intensity for crown fires
* @return the flame length
*/

float
crown_flame_length_k(float intensity)
{
float fl = 0.1 * pow(intensity, 0.5);
if (fl < 0.01)
{
return 0;
}
else
{
return std::ceil(fl * 100.0) / 100.0;
}
}

bool
fire_type(inputs* data, main_outs* at, int FMC)
{
Expand Down Expand Up @@ -935,6 +980,8 @@ calculate_k(inputs* data,
at->rss = hptr->ros;
bptr->ros = backfire_ros10_k(hptr, sec);
fptr->ros = flankfire_ros_k(hptr->ros, bptr->ros, sec->lb);
at->crown_intensity = crown_byram_intensity_k(at, data);
at->crown_flame_length = crown_flame_length_k(at->crown_intensity);

if (args->verbose)
{
Expand All @@ -957,6 +1004,8 @@ calculate_k(inputs* data,
at->rss = hptr->ros;
bptr->ros = backfire_ros10_k(hptr, sec);
fptr->ros = flankfire_ros_k(hptr->ros, bptr->ros, sec->lb);
at->crown_intensity = crown_byram_intensity_k(at, data);
at->crown_flame_length = crown_flame_length_k(at->crown_intensity);

if (args->verbose)
{
Expand Down Expand Up @@ -1045,6 +1094,8 @@ determine_destiny_metrics_k(inputs* data, fuel_coefs* ptr, arguments* args, main
if (crownFire)
{
metrics->cfb = crownfractionburn(data, metrics, FMC);
metrics->crown_intensity = crown_byram_intensity_k(metrics, data);
metrics->crown_flame_length = crown_flame_length_k(metrics->crown_intensity);
}
if (args->verbose)
{
Expand Down
6 changes: 6 additions & 0 deletions Cell2Fire/FuelModelKitral.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ float backfire_ros_k(main_outs* at, snd_outs* sec);
// Flame length [m])
float flame_length(inputs* data, main_outs* at);

// Crown Flame length [m])
float crown_flame_length_k(float intensity);

// Angle of the flame w.r.t. horizontal surface (Putnam's)
float angleFL(inputs* data, main_outs* at);

Expand All @@ -41,6 +44,9 @@ float flame_height(inputs* data, main_outs* at);
// byram intensity
float byram_intensity(inputs* data, main_outs* at);

// crown byram intensity
float crown_byram_intensity_k(main_outs* at, inputs* data);

// Type of fire (Crown = 1, SROS = 0)
bool fire_type(inputs* data, main_outs* atr, int FMC);
// Active crown
Expand Down
5 changes: 5 additions & 0 deletions Cell2Fire/FuelModelSpain.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ float backfire_ros_s(main_outs* at, snd_outs* sec);

// Flame length [m])
float flame_length(inputs* data, fuel_coefs* ptr);
// Crown Flame length [m])
float crown_flame_length(float intensity);

// Angle of the flame w.r.t. horizontal surface (Putnam's)
float angleFL(inputs* data, fuel_coefs* ptr);
Expand All @@ -45,6 +47,9 @@ float flame_height(inputs* data, fuel_coefs* ptr);
// byram intensity
float byram_intensity(inputs* data, fuel_coefs* ptr);

// crown byram intensity
float crown_byram_intensity(main_outs* at, inputs* data);

// Type of fire (Crown = 1, SROS = 0)
bool fire_type(inputs* data, fuel_coefs* ptr);

Expand Down
11 changes: 6 additions & 5 deletions Cell2Fire/ReadArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,17 @@ parseArgs(int argc, char* argv[], arguments* args_ptr)
//}

//--statistics
// if (cmdOptionExists(argv, argv + argc, "--statistics")) {
// out_stats = true;
// printf("Statistics: %d \n", out_stats);
//}
if (cmdOptionExists(argv, argv + argc, "--statistics"))
{
out_stats = true;
printf("Statistics: %d \n", out_stats);
}

//--bbo
if (cmdOptionExists(argv, argv + argc, "--bbo"))
{
bbo_tuning = true;
printf("BBOTuning: %s \n", btoa(out_stats));
printf("BBOTuning: %s \n", btoa(bbo_tuning));
}

//--cros
Expand Down
33 changes: 33 additions & 0 deletions Cell2Fire/WriteCSV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,39 @@ CSVWriter::printIgnitions(std::unordered_map<int, int> ignitionsHistory,
ofs.close();
}

void
CSVWriter::printStats(std::unordered_map<int, std::vector<float>> statistics)
{
std::ofstream ofs(fileName, std::ofstream::out);

// Print column titles
ofs << "cell,surfaceFlameLength,crownFlameLength,maxFlameLength\n";

// Iterate through the unordered_map using iterator
for (auto it = statistics.begin(); it != statistics.end(); ++it)
{
int sim = it->first; // The simulation ID (key)
const std::vector<float>& flameLengths = it->second; // The associated flame lengths (value)

ofs << sim; // Print the simulation number (key)

// Print all the flame lengths associated with the current simulation
for (size_t j = 0; j < flameLengths.size(); j++)
{
ofs << "," << flameLengths[j];
if (j < flameLengths.size() - 1)
{
ofs << " "; // Optional: space between multiple flame lengths
}
}

ofs << "\n"; // Move to the next line for each entry
}

// Close the file
ofs.close();
}

void
CSVWriter::printCSV_V2(int rows, int cols, std::vector<int> statusCells)
{
Expand Down
1 change: 1 addition & 0 deletions Cell2Fire/WriteCSV.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class CSVWriter
void printWeather(std::vector<std::string> weatherHistory);
void printIgnitions(std::unordered_map<int, int> ignitionsHistory,
std::unordered_map<int, std::string> weatherHistory);
void printStats(std::unordered_map<int, std::vector<float>> statistics);
void printCSV_V2(int rows, int cols, std::vector<int> statusCells);
// Function to create a directory
void MakeDir(std::string pathPlot);
Expand Down