diff --git a/src/config/config.cpp b/src/config/config.cpp new file mode 100644 index 0000000..5be6f2a --- /dev/null +++ b/src/config/config.cpp @@ -0,0 +1,150 @@ +#include "Matrix.h" +#define GLOBLE_CONFIG +#include "config.h" + +namespace Recon +{ + void initalizeConfig() + { + //reconParams.measurementInfo.ce + reconParams::useCEMeasured = true; + reconParams::removeOutliersFromCEMeasured = true; + reconParams::offsetFilterEnabled = 6.9e-6; + reconParams::offsetFilterDisabled = 1.2e-6; + //reconParams.measurementInfo.temp + reconParams::useTASTempComp = true; + reconParams::correctTASTemp = 1; + //reconParams.hardwareSelection + reconParams::gpuSelectionList = Aurora::Matrix::fromRawData(new double[8] {0,1,2,3,4,5,6,7},8); + //reconParams.dataInfo + reconParams::expectedAScanDataLength = 4000; + + //reflectParams.dataSelection + reflectParams::senderTasList = Aurora::Matrix::fromRawData(new double[128] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128},128); //1~128 + reflectParams::senderElementList = Aurora::Matrix::fromRawData(new double[18] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},18); //1~18 + reflectParams::receiverTasList = Aurora::Matrix::fromRawData(new double[128] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128},128); //1~128 + reflectParams::receiverElementList = Aurora::Matrix::fromRawData(new double[18] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},18); //1~18 + reflectParams::motorPos = Aurora::Matrix::fromRawData(new double[2] {1,2}, 2); + reflectParams::constricReflectionAngles = 1; + reflectParams::angleLowerLimit = 45; + reflectParams::angleUpperLimit = 360; + reflectParams::findDefects = 1; + reflectParams::epsilon = 10; + //reflectParams.dataBlocking + reflectParams::mpSize = 1; + reflectParams::senderTASSize = 2; + reflectParams::senderElementSize = 18; + //reflectParams.qualityCheck + reflectParams::qualityCheck = true; + reflectParams::warningThreshold = 0.5; + reflectParams::errorThreshold = 0.1; + //reflectParams.dataPreparation + reflectParams::version = 2; + reflectParams::aScanReconstructionFrequency = 10000000; + reflectParams::offsetElectronic = 5.2e-7; + reflectParams::removeDCOffset = true; + reflectParams::expectedAScanDataLength = 4000; + //reflectParams.imageInfos + reflectParams::pixelResolutionX = 400; + reflectParams::pixelResolutionY = 400; + reflectParams::pixelResolutionZ = NAN; + reflectParams::imageStartpoint = Aurora::Matrix::fromRawData(new double[3] {-0.18,-0.18,-0.22}, 1, 3); + reflectParams::imageEndpoint = Aurora::Matrix::fromRawData(new double[3] {0.18,0.18,0.02}, 1, 3); + reflectParams::imageResolution = NAN; + reflectParams::imageXYZ = Aurora::Matrix(); + //reflectParams.signalProcessing + reflectParams::useOptPulse = 1; + reflectParams::optPulseFactor = 48; + reflectParams::expectedPulseLength = 90; + reflectParams::limitNumPulsesTo = 100; + reflectParams::normalizePeaks = 1; + reflectParams::removeTransmissionSignal = 1; + reflectParams::suppressSameHead = 1; + reflectParams::suppressSameHeadLength = 1500; + reflectParams::useCorrelation = 1; + reflectParams::matchedFilterCeAScan = true; + reflectParams::windowLength = 10; + reflectParams::numThreads = 30; + reflectParams::expectedUSSpeedRange = Aurora::Matrix::fromRawData(new double[2] {1420,1600}, 1, 2); + //reflectParams.transmissionCorrection + reflectParams::soundSpeedCorrection = 1; + reflectParams::attenuationCorrection = 1; + reflectParams::saveTransmInReflCoords = 1; + reflectParams::resolutionTransmMap = 0.005; + //reflectParams.saft + reflectParams::debugMode = 0; + reflectParams::blockSizeReco = 60000; + reflectParams::medianWindowSize = 1; + reflectParams::saftVariant = Aurora::Matrix::fromRawData(new double[6]{1,1,1,1,0,0} , 1, 6); + reflectParams::useAscanIndex = 1; + reflectParams::attenuationCorrectionLimit = 20; + reflectParams::blockDimXYZ = Aurora::Matrix::fromRawData(new double[3]{16,16,1} , 1, 3); + //reflectParams + reflectParams::VERSION_MATLAB_MAJOR = 9; + reflectParams::OS_UNIX = 0; + reflectParams::runReflectionReco = true; + + transParams::gpuSelectionList = reconParams::gpuSelectionList; + //transParams.dataSelection + transParams::verbose = 1; + transParams::saveRecon = 1; + transParams::saveDebugInfomation = 1; + //transParams.dataSelection + transParams::senderTasList = Aurora::Matrix::fromRawData(new double[128] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128},128); //1~128 + transParams::senderElementList = Aurora::Matrix::fromRawData(new double[18] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},18); //1~18 + transParams::receiverTasList = Aurora::Matrix::fromRawData(new double[128] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128},128); //1~128 + transParams::receiverElementList = Aurora::Matrix::fromRawData(new double[18] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},18); //1~18 + transParams::motorPos = Aurora::Matrix::fromRawData(new double[2] {1,2}, 2); + transParams::filterSensitivity = 1; + transParams::sensFilter = 0.3; + transParams::angleLowerLimit = 120; + transParams::angleUpperLimit = 180; + transParams::applyCalib = true; + transParams::snrThreshold = 10; + transParams::calibReferenceTas = Aurora::Matrix::fromRawData(new double[1] {1},1); + transParams::calibReferenceMotorPosition = Aurora::Matrix::fromRawData(new double[1] {1},1); + transParams::constrictReflectionAngles = 0; + //transParams.qualityCheck + transParams::qualityCheck = 1; + transParams::warningThreshold = 0.5; + transParams::errorThreshold = 0.1; + //transParams.dataBlocking + transParams::mpSize = 1; + transParams::senderTASSize = 2; + transParams::senderElementSize = 18; + //transParams.dataPreparation + transParams::numPixelXY = 128; + transParams::offsetElectronic = 5.2e-7; + transParams::aScanReconstructionFrequency = 10000000; + transParams::minTemperature = 15; + transParams::maxTemperature = 40; + //transParams.detection + transParams::forceRedetect = 0; + transParams::saveDetection = 0; + transParams::version = 1; + transParams::useTimeWindowing = 1; + transParams::gaussWindow = 0; + transParams::outlierOnTasDetection = 0; + transParams::resampleFactor = 1; + transParams::nThreads = 8; + transParams::minSpeedOfSound = 1450; + transParams::maxSpeedOfSound = 1550; + transParams::detectionWindowSOS = 1; + transParams::detectionWindowATT = 50; + transParams::pulseLengthSamples = 0; + transParams::pulseLengthRefSamples = 0; + //transParams.rayTracing + transParams::bentReconstruction = false; + transParams::bresenham = 1; + transParams::bentMethod = 1; + transParams::bentTol = 1; + transParams::bentIter = 1; + //transParams.solver + transParams::name = "TVAL3"; + transParams::maxIter = 50; + transParams::muValues = Aurora::Matrix::fromRawData(new double[1] {100}, 1); + transParams::betaValues = Aurora::Matrix::fromRawData(new double[1] {1}, 1); + transParams::runTransmissionReco = true; + transParams::nonNeg = false; + } +} diff --git a/src/config/config.h b/src/config/config.h index 99d2dff..8c38464 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -1,157 +1,167 @@ #ifndef RECON_CONFIG_H #define RECON_CONFIG_H +#ifdef GLOBLE_CONFIG +#define EXTERN_C +#else +#define EXTERN_C extern +#endif + #include #include "Matrix.h" - namespace Recon { namespace reconParams { //reconParams.measurementInfo.ce - static bool useCEMeasured = true; - static bool removeOutliersFromCEMeasured = true; - static double offsetFilterEnabled = 6.9e-6; - static double offsetFilterDisabled = 1.2e-6; + EXTERN_C bool useCEMeasured; + EXTERN_C bool removeOutliersFromCEMeasured; + EXTERN_C double offsetFilterEnabled; + EXTERN_C double offsetFilterDisabled; //reconParams.measurementInfo.temp - static bool useTASTempComp = true; - static bool correctTASTemp = 1; + EXTERN_C bool useTASTempComp; + EXTERN_C bool correctTASTemp; //reconParams.hardwareSelection - static Aurora::Matrix gpuSelectionList = Aurora::Matrix::fromRawData(new double[8]{0,1,2,3,4,5,6,7},8); + EXTERN_C Aurora::Matrix gpuSelectionList; //reconParams.dataInfo - static int expectedAScanDataLength = 4000; + EXTERN_C int expectedAScanDataLength; } namespace reflectParams { //reflectParams.dataSelection - static Aurora::Matrix senderTasList = Aurora::Matrix::fromRawData(new double[128]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128},128);//1~128 - static Aurora::Matrix senderElementList = Aurora::Matrix::fromRawData(new double[18]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},18);//1~18 - static Aurora::Matrix receiverTasList = Aurora::Matrix::fromRawData(new double[128]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128},128);//1~128 - static Aurora::Matrix receiverElementList = Aurora::Matrix::fromRawData(new double[18]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},18);//1~18 - static Aurora::Matrix motorPos = Aurora::Matrix::fromRawData(new double[2]{1,2}, 2); - static int constricReflectionAngles = 1; - static int angleLowerLimit = 45; - static int angleUpperLimit = 360; - static int findDefects = 1; - static int epsilon = 10; + EXTERN_C Aurora::Matrix senderTasList; + EXTERN_C Aurora::Matrix senderElementList; + EXTERN_C Aurora::Matrix receiverTasList; + EXTERN_C Aurora::Matrix receiverElementList; + EXTERN_C Aurora::Matrix motorPos; + EXTERN_C int constricReflectionAngles; + EXTERN_C int angleLowerLimit; + EXTERN_C int angleUpperLimit; + EXTERN_C int findDefects; + EXTERN_C int epsilon; //reflectParams.dataBlocking - static int mpSize = 1; - static int senderTASSize = 2; - static int senderElementSize = 18; + EXTERN_C int mpSize; + EXTERN_C int senderTASSize; + EXTERN_C int senderElementSize; //reflectParams.qualityCheck - static bool qualityCheck = true; - static double warningThreshold = 0.5; - static double errorThreshold = 0.1; + EXTERN_C bool qualityCheck; + EXTERN_C double warningThreshold; + EXTERN_C double errorThreshold; //reflectParams.dataPreparation - static int version = 2; - static int aScanReconstructionFrequency = 10000000; - static double offsetElectronic = 5.2e-7; - static bool removeDCOffset = true; - static int expectedAScanDataLength = 4000; + EXTERN_C int version; + EXTERN_C int aScanReconstructionFrequency; + EXTERN_C double offsetElectronic; + EXTERN_C bool removeDCOffset; + EXTERN_C int expectedAScanDataLength; //reflectParams.imageInfos - static int pixelResolutionX = 400; - static int pixelResolutionY = 400; - static double imageStartpoint[3] = {-0.18,-0.18,-0.22}; - static double imageEndpoint[3] = {0.18,0.18,0.02}; + EXTERN_C double pixelResolutionX; + EXTERN_C double pixelResolutionY; + EXTERN_C double pixelResolutionZ; + EXTERN_C Aurora::Matrix imageStartpoint; + EXTERN_C Aurora::Matrix imageEndpoint; + EXTERN_C double imageResolution; + EXTERN_C Aurora::Matrix imageXYZ; //reflectParams.signalProcessing - static int useOptPulse = 1; - static int optPulseFactor = 48; - static int expectedPulseLength = 90; - static int limitNumPulsesTo = 100; - static int normalizePeaks = 1; - static int removeTransmissionSignal = 1; - static int suppressSameHead = 1; - static int suppressSameHeadLength = 1500; - static int useCorrelation = 1; - static bool matchedFilterCeAScan = true; - static int windowLength = 10; - static int numThreads = 30; - static int expectedUSSpeedRange[2] = {1420,1600}; + EXTERN_C int useOptPulse; + EXTERN_C int optPulseFactor; + EXTERN_C int expectedPulseLength; + EXTERN_C int limitNumPulsesTo; + EXTERN_C int normalizePeaks; + EXTERN_C int removeTransmissionSignal; + EXTERN_C int suppressSameHead; + EXTERN_C int suppressSameHeadLength; + EXTERN_C int useCorrelation; + EXTERN_C bool matchedFilterCeAScan; + EXTERN_C int windowLength; + EXTERN_C int numThreads; + EXTERN_C Aurora::Matrix expectedUSSpeedRange; //reflectParams.transmissionCorrection - static int soundSpeedCorrection = 1; - static int attenuationCorrection = 1; - static int saveTransmInReflCoords = 1; - static double resolutionTransmMap = 0.005; + EXTERN_C int soundSpeedCorrection; + EXTERN_C int attenuationCorrection; + EXTERN_C int saveTransmInReflCoords; + EXTERN_C double resolutionTransmMap; //reflectParams.saft - static int debugMode = 0; - static int blockSizeReco = 60000; - static int medianWindowSize = 1; - static int saftVariant[6] = {1,1,1,1,0,0}; - static int useAscanIndex = 1; - static int attenuationCorrectionLimit = 20; - static int blockDimXYZ[3] = {16,16,1}; + EXTERN_C int debugMode; + EXTERN_C int blockSizeReco; + EXTERN_C int medianWindowSize; + EXTERN_C Aurora::Matrix saftVariant; + EXTERN_C int useAscanIndex; + EXTERN_C int attenuationCorrectionLimit; + EXTERN_C Aurora::Matrix blockDimXYZ; //reflectParams - static int VERSION_MATLAB_MAJOR = 9; - static int OS_UNIX = 0; - static bool runReflectionReco = true; + EXTERN_C int VERSION_MATLAB_MAJOR; + EXTERN_C int OS_UNIX; + EXTERN_C bool runReflectionReco; } namespace transParams { - static Aurora::Matrix gpuSelectionList = reconParams::gpuSelectionList; + EXTERN_C Aurora::Matrix gpuSelectionList; //transParams.dataSelection - static int verbose = 1; - static int saveRecon = 1; - static int saveDebugInfomation = 1; + EXTERN_C int verbose; + EXTERN_C int saveRecon; + EXTERN_C int saveDebugInfomation; //transParams.dataSelection - static Aurora::Matrix senderTasList = Aurora::Matrix::fromRawData(new double[128]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128},128);//1~128 - static Aurora::Matrix senderElementList = Aurora::Matrix::fromRawData(new double[18]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},18);//1~18 - static Aurora::Matrix receiverTasList = Aurora::Matrix::fromRawData(new double[128]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128},128);//1~128 - static Aurora::Matrix receiverElementList = Aurora::Matrix::fromRawData(new double[18]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},18);//1~18 - static Aurora::Matrix motorPos = Aurora::Matrix::fromRawData(new double[2]{1,2}, 2); - static int filterSensitivity = 1; - static double sensFilter = 0.3; - static int angleLowerLimit = 120; - static int angleUpperLimit = 180; - static bool applyCalib = true; - static int snrThreshold = 10; - static Aurora::Matrix calibReferenceTas = Aurora::Matrix::fromRawData(new double[1]{1},1); - static Aurora::Matrix calibReferenceMotorPosition = Aurora::Matrix::fromRawData(new double[1]{1},1); - static int constrictReflectionAngles = 0; + EXTERN_C Aurora::Matrix senderTasList; + EXTERN_C Aurora::Matrix senderElementList; + EXTERN_C Aurora::Matrix receiverTasList; + EXTERN_C Aurora::Matrix receiverElementList; + EXTERN_C Aurora::Matrix motorPos; + EXTERN_C int filterSensitivity; + EXTERN_C double sensFilter; + EXTERN_C int angleLowerLimit; + EXTERN_C int angleUpperLimit; + EXTERN_C bool applyCalib; + EXTERN_C int snrThreshold; + EXTERN_C Aurora::Matrix calibReferenceTas; + EXTERN_C Aurora::Matrix calibReferenceMotorPosition; + EXTERN_C int constrictReflectionAngles; //transParams.qualityCheck - static int qualityCheck = 1; - static double warningThreshold = 0.5; - static double errorThreshold = 0.1; + EXTERN_C int qualityCheck; + EXTERN_C double warningThreshold; + EXTERN_C double errorThreshold; //transParams.dataBlocking - static int mpSize = 1; - static int senderTASSize = 2; - static int senderElementSize = 18; + EXTERN_C int mpSize; + EXTERN_C int senderTASSize; + EXTERN_C int senderElementSize; //transParams.dataPreparation - static int numPixelXY = 128; - static double offsetElectronic = 5.2e-7; - static int aScanReconstructionFrequency = 10000000; - static double minTemperature = 15; - static double maxTemperature = 40; + EXTERN_C int numPixelXY; + EXTERN_C double offsetElectronic; + EXTERN_C int aScanReconstructionFrequency; + EXTERN_C double minTemperature; + EXTERN_C double maxTemperature; //transParams.detection - static int forceRedetect = 0; - static int saveDetection = 0; - static int version = 1; - static int useTimeWindowing = 1; - static int gaussWindow = 0; - static int outlierOnTasDetection = 0; - static int resampleFactor = 1; - static int nThreads = 8; - static int minSpeedOfSound = 1450; - static int maxSpeedOfSound = 1550; - static int detectionWindowSOS = 1; - static int detectionWindowATT = 50; - static double pulseLengthSamples = 0; - static double pulseLengthRefSamples = 0; + EXTERN_C int forceRedetect; + EXTERN_C int saveDetection; + EXTERN_C int version; + EXTERN_C int useTimeWindowing; + EXTERN_C int gaussWindow; + EXTERN_C int outlierOnTasDetection; + EXTERN_C int resampleFactor; + EXTERN_C int nThreads; + EXTERN_C int minSpeedOfSound; + EXTERN_C int maxSpeedOfSound; + EXTERN_C int detectionWindowSOS; + EXTERN_C int detectionWindowATT; + EXTERN_C double pulseLengthSamples; + EXTERN_C double pulseLengthRefSamples; //transParams.rayTracing - static bool bentReconstruction = false; - static int bresenham = 1; - static int bentMethod = 1; - static int bentTol = 1; - static int bentIter = 1; + EXTERN_C bool bentReconstruction; + EXTERN_C int bresenham; + EXTERN_C int bentMethod; + EXTERN_C int bentTol; + EXTERN_C int bentIter; //transParams.solver - static std::string name = "TVAL3"; - static int maxIter = 50; - static Aurora::Matrix muValues = Aurora::Matrix::fromRawData(new double[1]{100}, 1); - static Aurora::Matrix betaValues = Aurora::Matrix::fromRawData(new double[1]{1}, 1); - static bool runTransmissionReco = true; - static bool nonNeg = false; + EXTERN_C std::string name; + EXTERN_C int maxIter; + EXTERN_C Aurora::Matrix muValues; + EXTERN_C Aurora::Matrix betaValues; + EXTERN_C bool runTransmissionReco; + EXTERN_C bool nonNeg; } + + void initalizeConfig(); } #endif //RECON_CONFIG_H \ No newline at end of file