#include "stdafx.h" #include "PorosityInput.h" #include "PorositySSADialog.h" using namespace std; //CInputDialog InputDlg; void disable_inputs(PorositySSADialog* PoroDlg){ //common inputs disabled in dialog class //run settings PoroDlg->check_run_3D_struct.EnableWindow(FALSE); PoroDlg->field_pixel_size_cntrl.EnableWindow(FALSE); PoroDlg->field_buckets_cntrl.EnableWindow(FALSE); PoroDlg->check_bucket_match_pixel_size.EnableWindow(FALSE); PoroDlg->field_bucket_size_mult_cntrl.EnableWindow(FALSE); } /* re-enable the windows after an analysis run is done */ void enable_inputs(PorositySSADialog* PoroDlg){ //enable the common inputs PoroDlg->EnableCommonInputs(); //run settings PoroDlg->check_run_3D_struct.EnableWindow(TRUE); PoroDlg->field_pixel_size_cntrl.EnableWindow(TRUE); PoroDlg->check_bucket_match_pixel_size.EnableWindow(TRUE); if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) PoroDlg->field_bucket_size_mult_cntrl.EnableWindow(TRUE); else PoroDlg->field_buckets_cntrl.EnableWindow(TRUE); //flash for 3 seconds to alert user that we are done PoroDlg->FlashWindowEx(FLASHW_TRAY, 3, 0); } //returns 0 if successful int porosity_excel_prep(PorositySSADialog* PoroDlg, int dist_offset) { //reading SSA~sample_name~.txt char filename_SSA[1024]; register unsigned short i; char name[1024]; float porosity, ssam2m3, ssam2g; unsigned long int totvol, totvolsampled, totvolpore, totintarea; char fstats[512]; char *line = new char[1024]; float m_rh_xy; int last_valid_xy=0; float *rh_xy; float m_rh_yz; int last_valid_yz=0; float *rh_yz; float m_rh_zx; int last_valid_zx=0; float *rh_zx; float cur_size; int pix_jump_val = PoroDlg->field_bucket_size_mult_int; // 2 used if only odd radius desired, if all then should be 1' short bins = PoroDlg->field_buckets_short; //# of bins for the histogram ifstream infile; float pixsize = PoroDlg->field_pixel_size_float; sprintf(filename_SSA, "%sPorositySSA\\%s_SSA.txt", PoroDlg->field_directory_work_str, PoroDlg->field_name_output_str); ifstream file_SSA(filename_SSA); if(!file_SSA.is_open()) { write_to_log("Porosity: Excel Prep: cannot open file %s", filename_SSA); return 1; } //file_SSA>>name>>name; //getting rid of the first line file_SSA.getline(line, 1024, '\n'); file_SSA>>name>>porosity; file_SSA>>name>>ssam2m3>>name; file_SSA>>name>>ssam2g>>name; file_SSA>>name>>totvol>>name; file_SSA>>name>>totvolsampled>>name; file_SSA>>name>>totvolpore>>name; file_SSA>>name>>totintarea>>name; file_SSA.close(); //reading xy_stats_rh-area.txt sprintf(fstats, "%sPorositySSA\\%s_xy_stats_rh-area.txt", PoroDlg->field_directory_work_str, PoroDlg->field_name_output_str);//"%s_xy_stats_rh-area.txt", PoroDlg->); infile.open(fstats); if(!infile.is_open()) { write_to_log("Porosity: Excel Prep: cannot open file %s", fstats); return 1; } //getting rid of the first line infile.getline(line, 1024, '\n'); infile>>name>>name>>name>>m_rh_xy; //getting rid of the 3rd & 4th line infile.getline(line, 1024, '\n'); infile.getline(line, 1024, '\n'); infile.getline(line, 1024, '\n'); if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) rh_xy = new float[bins*2+2]; else rh_xy = new float[1024]; if(!rh_xy) { write_to_log("Porosity: Excel Prep: out of memory -rh_xy-"); return 2; } cur_size = pixsize; rh_xy[0] = 0.0f; for (i=0; i<bins; i++) { float a, b; infile >> a >> b; // Check if bucket size same as pixel is used, or number of buckets if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) { if ( (a*4*pixsize) > cur_size) { // Move to next pixel size while ( (a*4*pixsize) > cur_size ) { cur_size += (pixsize*pix_jump_val); ++last_valid_xy; rh_xy[last_valid_xy] = 0.0f; } } // Now we are in correct bucket, accumulate percentage rh_xy[last_valid_xy] += b; } else { rh_xy[2*i] = a*4*pixsize; // Convert to diameter rh_xy[2*i+1] = b; } } infile.close(); //reading yz_stats_rh-area.txt sprintf(fstats, "%sPorositySSA\\%s_yz_stats_rh-area.txt", PoroDlg->field_directory_work_str, PoroDlg->field_name_output_str);//"yz_stats_rh-area.txt"); infile.open(fstats); if(!infile.is_open()) { write_to_log("Porosity: Excel Prep: cannot open file %s", fstats); return 1; } //getting rid of the first line infile.getline(line, 1024, '\n'); infile>>name>>name>>name>>m_rh_yz; //getting rid of the 3rd & 4th line infile.getline(line, 1024, '\n'); infile.getline(line, 1024, '\n'); infile.getline(line, 1024, '\n'); if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) rh_yz = new float[bins*2+2]; else rh_yz = new float[1024]; if(!rh_yz) { write_to_log("Porosity: Excel Prep: out of memory -rh_yz-"); return 2; } cur_size = pixsize; rh_yz[0] = 0.0f; for (i=0; i<bins; i++) { float a,b; infile>>a>>b; // Check if bucket size same as pixel is used, or number of buckets if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) { if ((a*4*pixsize)> cur_size) { // Move to next pixel size while ( (a*4*pixsize) > cur_size ) { cur_size += (pixsize*pix_jump_val); ++last_valid_yz; rh_yz[last_valid_yz] = 0.0f; } } // Now we are in correct bucket, accumulate percentage rh_yz[last_valid_yz] += b; } else { rh_yz[2*i] = a*4*pixsize; // Convert to diameter rh_yz[2*i+1] = b; } } infile.close(); //reading zx_stats_rh-area.txt sprintf(fstats, "%sPorositySSA\\%s_zx_stats_rh-area.txt", PoroDlg->field_directory_work_str, PoroDlg->field_name_output_str);//"zx_stats_rh-area.txt"); infile.open(fstats); if(!infile.is_open()) { write_to_log("Porosity: Excel Prep: cannot open file %s", fstats); return 1; } //getting rid of the first line infile.getline(line, 1024, '\n'); infile>>name>>name>>name>>m_rh_zx; //getting rid of the 3rd & 4th line infile.getline(line, 1024, '\n'); infile.getline(line, 1024, '\n'); infile.getline(line, 1024, '\n'); if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) rh_zx = new float[bins*2+2]; else rh_zx = new float[1024]; if(!rh_zx) { write_to_log("Porosity: Excel Prep: out of memory -rh_zx-"); return 2; } cur_size = pixsize; rh_zx[0] = 0.0f; for (i=0; i<bins; i++) { float a,b; infile>>a>>b; // Check if bucket size same as pixel is used, or number of buckets if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) { if ( (a*4*pixsize) > cur_size) { // Move to next pixel size while ( (a*4*pixsize) > cur_size ) { cur_size += (pixsize*pix_jump_val); ++last_valid_zx; rh_zx[last_valid_zx] = 0.0f; } } // Now we are in correct bucket, accumulate percentage rh_zx[last_valid_zx] += b; } else { rh_zx[2*i] = a*4*pixsize; // Convert to diameter rh_zx[2*i+1] = b; } } infile.close(); //convert to diameters (*4) in microns (*pixelsize) m_rh_xy *= 4*pixsize; m_rh_yz *= 4*pixsize; m_rh_zx *= 4*pixsize; //creating the xcel .csv file char excel_out_file[512]; sprintf(excel_out_file, "%sPorositySSA\\%s_PorositySSA_results.csv", PoroDlg->field_directory_work_str, PoroDlg->field_name_output_str); //do common header PoroDlg->Write_Result_Header(excel_out_file); //reopen in append mode ofstream fout; fout.open(excel_out_file, ios::out | ios::app); if(!fout.is_open()) { write_to_log("Porosity: Excel Prep: cannot open file %s", excel_out_file); return 1; } //results fout<<"Analysis Results"<<endl; fout<<"Porosity,"<<porosity<<endl; fout<<"SSA,"<<ssam2m3<<",m2/m3"<<endl; fout<<","<<ssam2g<<",m2/g"<<endl<<endl; fout<<"Total Volume,"<<totvol<<",pixelcu,"<<totvol*pixsize*pixsize*pixsize/1000000000<<",mmcu"<<endl; fout<<"Total Volume 4 SSA,"<<totvolsampled<<",pixelcu,"<<totvolsampled*pixsize*pixsize*pixsize/1000000000<<",mmcu"<<endl; fout<<"Total Volume of Pores,"<<totvolpore<<",pixelcu,"<<totvolpore*pixsize*pixsize*pixsize/1000000000<<",mmcu"<<endl; fout<<"Total Interface Area,"<<totvol<<",pixelsq,"<<totvol*pixsize*pixsize/1000000<<",mmsq"<<endl<<endl; fout<<"Pore Diameter (microns),Pore Volume/Total Pore Volume"<<endl; fout<<",Transverse,,In_Plane1,,In_Plane2"<<endl; fout<<"Mean,"<<m_rh_xy<<",,"<<m_rh_yz<<",,"<<m_rh_zx<<endl<<endl; // If requested, write out empty lines before distribution. This is used to ensure that // the distribution always starts on a particular line for easy copy/past if ( dist_offset > 0 ) { fout << endl << "***** See line #" << dist_offset << " for distribution. *****" << endl; // Need to close file first fout.close(); // One less line offset to match Sphere distribution (two lines used for more header below) if ( OpenFileForAppendAtLine(dist_offset-1, excel_out_file, fout) != 0 ) { write_to_log("SphereGrowth::RunAnalysis - Error reopening file '%s' after distribution offset.", excel_out_file); return 1; } } else fout<<"Distribution (%Total Pore volume)"; if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) { // Buckets multiple of pixel size format fout<<endl<<"diameter (microns),XY(%vol),YZ(%vol),ZX(%vol)"<<endl; } else { // Number of buckets specified fout<<",,,,,,,Normalized Distribution(%vol per unit bucket)"<<endl; fout<<"diameter (microns),XY(%vol),diameter,YZ(%vol),diameter,ZX(%vol),,XY,YZ,ZX"<<endl; } int last_bucket_of_all = last_valid_xy; if ( last_bucket_of_all < last_valid_yz ) last_bucket_of_all = last_valid_yz; if ( last_bucket_of_all < last_valid_zx ) last_bucket_of_all = last_valid_zx; if ( PoroDlg->check_bucket_match_pixel_size.GetCheck() ) { // Buckets multiple of pixel size format for (i = 0; i < last_bucket_of_all; i++) { // Print out pixel size fout << i*pixsize*pix_jump_val + pixsize; // Print XY if still valid range if ( i <= last_valid_xy ) fout << "," << rh_xy[i]; else fout << ",,"; // Print YZ if still valid range if ( i <= last_valid_yz ) fout << "," << rh_yz[i]; else fout << ",,"; // Print ZX if still valid range if ( i <= last_valid_zx ) fout << "," << rh_zx[i]; else fout << ",,"; // Go to next line fout << endl; } } else { // Bucket number format for (i=0; i<bins; i++) { fout<<rh_xy[2*i]<<","<<rh_xy[2*i+1]<<"," <<rh_yz[2*i]<<","<<rh_yz[2*i+1]<<"," <<rh_zx[2*i]<<","<<rh_zx[2*i+1]<<",," <<rh_xy[2*i+1]/2/rh_xy[0]<<"," //normalised <<rh_yz[2*i+1]/2/rh_yz[0]<<"," // <<rh_zx[2*i+1]/2/rh_zx[0]<<endl; // } } fout.close(); //free mem if (line) delete[] line; if (rh_xy) delete[] rh_xy; if (rh_yz) delete[] rh_yz; if (rh_zx) delete[] rh_zx; return 0; } UINT PorositySSASetup(LPVOID pParam) { int poro_return = 0; DS_1b_cube *orig_ds_cube; char work_directory[512];; char data_out_prefix[512]; char poro_directory[512]; PorositySSADialog* PoroDlg = (PorositySSADialog*) pParam; //disable all inputs for dialog disable_inputs(PoroDlg); write_to_log("PorositySSA: inputs disabled, starting setup."); sprintf(work_directory, "%s", PoroDlg->field_directory_work_str); sprintf(data_out_prefix, "%sPorositySSA\\%s", work_directory, PoroDlg->field_name_output_str); sprintf(poro_directory, "%sPorositySSA", work_directory); if (!CreateDirectory(poro_directory,NULL)) //create a new porosity directory if needed write_to_log("PorositySSA: 'PorositySSA' directory already exists, new one will not be created."); // read common user interface stuff, to get a cDS input orig_ds_cube = PoroDlg->Dlg_Input_to_cDS(); if (!orig_ds_cube) { PoroDlg->txt_field_progress.SetWindowText("Invalid input file type detected."); enable_inputs(PoroDlg); return 1; } //run porositySSA PoroDlg->txt_field_progress.SetWindowText("Now running Porosity SSA analysis..."); porositySSA(orig_ds_cube, data_out_prefix, (void*) PoroDlg); if ( PoroDlg->check_run_3D_struct.GetCheck() && (!PoroDlg->stop_request) ){ DS_1b_cube *cDS_cube_YZ, *cDS_cube_ZX; //pore distribution XY Dispore_All * dispore_XY = new Dispore_All(orig_ds_cube); PoroDlg->txt_field_progress.SetWindowText("Now performing dispore in XY plane..."); write_to_log("Porosity: Now performing 3D structure in XY plane."); poro_return = dispore_XY->run_dispore_all(data_out_prefix, "xy", &PoroDlg->pbar_simulation_progress, &PoroDlg->stop_request); delete dispore_XY; if (poro_return || PoroDlg->stop_request) goto error_handling; PoroDlg->txt_field_progress.SetWindowText("Now performing stats pore in XY plane..."); stats_pore_all(orig_ds_cube, PoroDlg->field_buckets_short, data_out_prefix, "xy"); //pore distribution YZ PoroDlg->txt_field_progress.SetWindowText("Now rotating YZ plane to top face..."); cDS_cube_YZ = orig_ds_cube->rotate_XY_to_YZ(); Dispore_All * dispore_YZ = new Dispore_All(cDS_cube_YZ); PoroDlg->txt_field_progress.SetWindowText("Now performing dispore in YZ plane..."); write_to_log("Porosity: Now performing 3D structure in YZ plane."); poro_return = dispore_YZ->run_dispore_all(data_out_prefix, "yz", &PoroDlg->pbar_simulation_progress, &PoroDlg->stop_request); delete dispore_YZ; delete cDS_cube_YZ; if (poro_return || PoroDlg->stop_request) goto error_handling; PoroDlg->txt_field_progress.SetWindowText("Now performing stats pore in YZ plane..."); stats_pore_all(orig_ds_cube, PoroDlg->field_buckets_short, data_out_prefix, "yz"); //pore distribution ZX PoroDlg->txt_field_progress.SetWindowText("Now rotating ZX plane to top face..."); cDS_cube_ZX = orig_ds_cube->rotate_XY_to_ZX(); Dispore_All * dispore_ZX = new Dispore_All(cDS_cube_ZX); PoroDlg->txt_field_progress.SetWindowText("Now performing dispore in ZX plane..."); write_to_log("Porosity: Now performing 3D structure in ZX plane."); poro_return = dispore_ZX->run_dispore_all(data_out_prefix, "zx", &PoroDlg->pbar_simulation_progress, &PoroDlg->stop_request); delete dispore_ZX; delete cDS_cube_ZX; if (poro_return || PoroDlg->stop_request) goto error_handling; //PoroDlg->txt_field_progress.SetWindowText("An error occured while running dispore YZ"); PoroDlg->txt_field_progress.SetWindowText("Now performing stats pore in ZX plane..."); stats_pore_all(orig_ds_cube, PoroDlg->field_buckets_short, data_out_prefix, "zx"); write_to_log("Porosity: 2D structure done for all planes, now preparing result file."); //write excel sheet PoroDlg->txt_field_progress.SetWindowText("Now writing excel sheet..."); porosity_excel_prep(PoroDlg, 50); } //clean up delete orig_ds_cube; error_handling: //error checking if ( poro_return != 0){ // incase the structure has no pore exit error if (poro_return == 1) { PoroDlg->txt_field_progress.SetWindowText("Error opening a file in dispore_all."); } if (poro_return == 2) { PoroDlg->txt_field_progress.SetWindowText("Error allocating memory."); } if (poro_return == 10) { write_to_log("Porosity run successfully aborted by user."); PoroDlg->StopConfirm(); } enable_inputs(PoroDlg); return 1; } //done PoroDlg->txt_field_progress.SetWindowText("Analysis complete!"); enable_inputs(PoroDlg); return 0; }