QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, const QString &name, QString *errorMessage) { // Resolve required symbols from the version.dll typedef DWORD (APIENTRY *GetFileVersionInfoSizeProtoType)(LPCTSTR, LPDWORD); typedef BOOL (APIENTRY *GetFileVersionInfoWProtoType)(LPCWSTR, DWORD, DWORD, LPVOID); typedef BOOL (APIENTRY *VerQueryValueWProtoType)(const LPVOID, LPWSTR lpSubBlock, LPVOID, PUINT); const char *versionDLLC = "version.dll"; QLibrary versionLib(QLatin1String(versionDLLC), 0); if (!versionLib.load()) { *errorMessage = msgCannotLoad(versionDLLC, versionLib.errorString()); return QString(); } // MinGW requires old-style casts GetFileVersionInfoSizeProtoType getFileVersionInfoSizeW = (GetFileVersionInfoSizeProtoType)(versionLib.resolve("GetFileVersionInfoSizeW")); GetFileVersionInfoWProtoType getFileVersionInfoW = (GetFileVersionInfoWProtoType)(versionLib.resolve("GetFileVersionInfoW")); VerQueryValueWProtoType verQueryValueW = (VerQueryValueWProtoType)(versionLib.resolve("VerQueryValueW")); if (!getFileVersionInfoSizeW || !getFileVersionInfoW || !verQueryValueW) { *errorMessage = msgCannotResolve(versionDLLC); return QString(); } // Now go ahead, read version info resource DWORD dummy = 0; const LPCTSTR fileName = reinterpret_cast<LPCTSTR>(name.utf16()); // MinGWsy const DWORD infoSize = (*getFileVersionInfoSizeW)(fileName, &dummy); if (infoSize == 0) { *errorMessage = QString::fromLatin1("Unable to determine the size of the version information of %1: %2").arg(name, winErrorMessage(GetLastError())); return QString(); } QByteArray dataV(infoSize + 1, '\0'); char *data = dataV.data(); if (!(*getFileVersionInfoW)(fileName, dummy, infoSize, data)) { *errorMessage = QString::fromLatin1("Unable to determine the version information of %1: %2").arg(name, winErrorMessage(GetLastError())); return QString(); } VS_FIXEDFILEINFO *versionInfo; const LPCWSTR backslash = TEXT("\\"); UINT len = 0; if (!(*verQueryValueW)(data, const_cast<LPWSTR>(backslash), &versionInfo, &len)) { *errorMessage = QString::fromLatin1("Unable to determine version string of %1: %2").arg(name, winErrorMessage(GetLastError())); return QString(); } QString rc; switch (t) { case WinDLLFileVersion: QTextStream(&rc) << HIWORD(versionInfo->dwFileVersionMS) << '.' << LOWORD(versionInfo->dwFileVersionMS); break; case WinDLLProductVersion: QTextStream(&rc) << HIWORD(versionInfo->dwProductVersionMS) << '.' << LOWORD(versionInfo->dwProductVersionMS); break; } return rc; }
void addToPowder(cEventData *eventData, cGlobal *global, int powderClass, long detIndex){ // Increment counter of number of powder patterns pthread_mutex_lock(&global->detector[detIndex].powderData_mutex[powderClass]); global->detector[detIndex].nPowderFrames[powderClass] += 1; if(detIndex == 0) global->nPowderFrames[powderClass] += 1; pthread_mutex_unlock(&global->detector[detIndex].powderData_mutex[powderClass]); double *buffer; FOREACH_DATAFORMAT_T(i_f, cDataVersion::DATA_FORMATS) { if (isBitOptionSet(global->detector[detIndex].powderFormat,*i_f)) { cDataVersion dataV(&eventData->detector[detIndex], &global->detector[detIndex], global->detector[detIndex].powderVersion, *i_f); while (dataV.next()) { float * data = dataV.getData(); double * powder = dataV.getPowder(powderClass); double * powder_squared = dataV.getPowderSquared(powderClass); long * powder_counter = dataV.getPowderCounter(powderClass); pthread_mutex_t * mutex = dataV.getPowderMutex(powderClass); // Powder squared buffer = (double*) calloc(dataV.pix_nn, sizeof(double)); if(!global->usePowderThresh) { for(long i=0; i<dataV.pix_nn; i++) // Use double precision throughout the multiplication to reduce rounding errors in powder_squared buffer[i] = ((double) data[i])*data[i]; } else { for(long i=0; i<dataV.pix_nn; i++){ if(data[i] > global->powderthresh) // Use double precision throughout the multiplication to reduce rounding errors in powder_squared buffer[i] = ((double) data[i])*data[i]; else buffer[i] = 0; } } if (global->threadSafetyLevel > 0) { pthread_mutex_lock(mutex); } if(global->detector[detIndex].savePowderMasked == 0 || powder_counter==NULL) { for(long i=0; i<dataV.pix_nn; i++){ // Powder powder[i] += data[i]; // Powder squared powder_squared[i] += buffer[i]; } } else if(global->detector[detIndex].savePowderMasked != 0 && powder_counter!=NULL) { uint16_t *pixelmask = eventData->detector[detIndex].pixelmask; uint16_t combined_pixel_options = PIXEL_IS_HOT|PIXEL_IS_BAD|PIXEL_IS_IN_JET; for(long i=0; i<dataV.pix_nn; i++){ if(isNoneOfBitOptionsSet(pixelmask[i], combined_pixel_options)) { // Powder powder[i] += data[i]; // Powder squared powder_squared[i] += buffer[i]; // Counter powder_counter[i] += 1; } } } if (global->threadSafetyLevel > 0) pthread_mutex_unlock(mutex); free(buffer); } } } /* * Sum of peaks centroids */ if (eventData->nPeaks > 0) { pthread_mutex_lock(&global->detector[detIndex].powderPeaks_mutex[powderClass]); long ci, cx, cy, e; double val; long pix_nn = global->detector[detIndex].pix_nn; long pix_nx = global->detector[detIndex].pix_nx; long pix_ny = global->detector[detIndex].pix_ny; for(long i=0; i<=eventData->peaklist.nPeaks && i<eventData->peaklist.nPeaks_max; i++) { // Peak position and value ci = eventData->peaklist.peak_com_index[i]; cx = lrint(eventData->peaklist.peak_com_x[i]); cy = lrint(eventData->peaklist.peak_com_y[i]); val = eventData->peaklist.peak_totalintensity[i]; // Bounds check if(cx < 0 || cx > (pix_nx-1) ) continue; if(cy < 0 || cy > (pix_ny-1) ) continue; if(ci < 0 || cx > (pix_nn-1) ) continue; // Element in 1D array e = cx + pix_nx*cy; if(e < 0 || e > (pix_nn-1) ) continue; global->detector[detIndex].powderPeaks[powderClass][e] += val; //global->detector[detIndex].powderPeaks[powderClass][ci] += val; } pthread_mutex_unlock(&global->detector[detIndex].powderPeaks_mutex[powderClass]); } // Min nPeaks if(eventData->nPeaks < global->nPeaksMin[powderClass]){ pthread_mutex_lock(&global->nPeaksMin_mutex[powderClass]); global->nPeaksMin[powderClass] = eventData->nPeaks; //memcpy(global->detector[detIndex].correctedMin[powderClass],eventData->detector[detIndex].corrected_data,sizeof(float)*pix_nn); pthread_mutex_unlock(&global->nPeaksMin_mutex[powderClass]); } // Max nPeaks if(eventData->nPeaks > global->nPeaksMax[powderClass]){ pthread_mutex_lock(&global->nPeaksMax_mutex[powderClass]); global->nPeaksMax[powderClass] = eventData->nPeaks; //memcpy(global->detector[detIndex].correctedMax[powderClass],eventData->detector[detIndex].corrected_data,sizeof(float)*pix_nn); pthread_mutex_unlock(&global->nPeaksMax_mutex[powderClass]); } }
int main(int argc, char ** argv) { MPI_Init(&argc, &argv); NcError error(NcError::silent_nonfatal); try { // Input filename std::string strInputFile; // Output filename std::string strOutputFile; // Separate topography file std::string strTopographyFile; // List of variables to extract std::string strVariables; // Extract geopotential height bool fGeopotentialHeight; // Pressure levels to extract std::string strPressureLevels; // Height levels to extract std::string strHeightLevels; // Extract variables at the surface bool fExtractSurface; // Extract total energy bool fExtractTotalEnergy; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputFile, "out", ""); CommandLineString(strVariables, "var", ""); CommandLineBool(fGeopotentialHeight, "output_z"); CommandLineBool(fExtractTotalEnergy, "output_energy"); CommandLineString(strPressureLevels, "p", ""); CommandLineString(strHeightLevels, "z", ""); CommandLineBool(fExtractSurface, "surf"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check command line arguments if (strInputFile == "") { _EXCEPTIONT("No input file specified"); } if (strOutputFile == "") { _EXCEPTIONT("No output file specified"); } if (strVariables == "") { _EXCEPTIONT("No variables specified"); } // Parse variable string std::vector< std::string > vecVariableStrings; ParseVariableList(strVariables, vecVariableStrings); // Check variables if (vecVariableStrings.size() == 0) { _EXCEPTIONT("No variables specified"); } // Parse pressure level string std::vector<double> vecPressureLevels; ParseLevelArray(strPressureLevels, vecPressureLevels); int nPressureLevels = (int)(vecPressureLevels.size()); for (int k = 0; k < nPressureLevels; k++) { if (vecPressureLevels[k] <= 0.0) { _EXCEPTIONT("Non-positive pressure values not allowed"); } } // Parse height level string std::vector<double> vecHeightLevels; ParseLevelArray(strHeightLevels, vecHeightLevels); int nHeightLevels = (int)(vecHeightLevels.size()); // Check pressure levels if ((nPressureLevels == 0) && (nHeightLevels == 0) && (!fExtractSurface) ) { _EXCEPTIONT("No pressure / height levels to process"); } // Open input file AnnounceStartBlock("Loading input file"); NcFile ncdf_in(strInputFile.c_str(), NcFile::ReadOnly); if (!ncdf_in.is_valid()) { _EXCEPTION1("Unable to open file \"%s\" for reading", strInputFile.c_str()); } // Load time array Announce("Time"); NcVar * varTime = ncdf_in.get_var("time"); if (varTime == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"time\"", strInputFile.c_str()); } int nTime = varTime->get_dim(0)->size(); DataArray1D<double> dTime(nTime); varTime->set_cur((long)0); varTime->get(&(dTime[0]), nTime); // Load latitude array Announce("Latitude"); NcVar * varLat = ncdf_in.get_var("lat"); if (varLat == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lat\"", strInputFile.c_str()); } int nLat = varLat->get_dim(0)->size(); DataArray1D<double> dLat(nLat); varLat->set_cur((long)0); varLat->get(&(dLat[0]), nLat); // Load longitude array Announce("Longitude"); NcVar * varLon = ncdf_in.get_var("lon"); if (varLon == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lon\"", strInputFile.c_str()); } int nLon = varLon->get_dim(0)->size(); DataArray1D<double> dLon(nLon); varLon->set_cur((long)0); varLon->get(&(dLon[0]), nLon); // Load level array Announce("Level"); NcVar * varLev = ncdf_in.get_var("lev"); if (varLev == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lev\"", strInputFile.c_str()); } int nLev = varLev->get_dim(0)->size(); DataArray1D<double> dLev(nLev); varLev->set_cur((long)0); varLev->get(&(dLev[0]), nLev); // Load level interface array Announce("Interface"); NcVar * varILev = ncdf_in.get_var("ilev"); int nILev = 0; DataArray1D<double> dILev; if (varILev == NULL) { Announce("Warning: Variable \"ilev\" not found"); } else { nILev = varILev->get_dim(0)->size(); if (nILev != nLev + 1) { _EXCEPTIONT("Variable \"ilev\" must have size lev+1"); } dILev.Allocate(nILev); varILev->set_cur((long)0); varILev->get(&(dILev[0]), nILev); } // Load topography Announce("Topography"); NcVar * varZs = ncdf_in.get_var("Zs"); if (varZs == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"Zs\"", strInputFile.c_str()); } DataArray2D<double> dZs(nLat, nLon); varZs->set_cur((long)0, (long)0); varZs->get(&(dZs[0][0]), nLat, nLon); AnnounceEndBlock("Done"); // Open output file AnnounceStartBlock("Constructing output file"); NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace); if (!ncdf_out.is_valid()) { _EXCEPTION1("Unable to open file \"%s\" for writing", strOutputFile.c_str()); } CopyNcFileAttributes(&ncdf_in, &ncdf_out); // Output time array Announce("Time"); NcDim * dimOutTime = ncdf_out.add_dim("time"); NcVar * varOutTime = ncdf_out.add_var("time", ncDouble, dimOutTime); varOutTime->set_cur((long)0); varOutTime->put(&(dTime[0]), nTime); CopyNcVarAttributes(varTime, varOutTime); // Output pressure array NcDim * dimOutP = NULL; NcVar * varOutP = NULL; if (nPressureLevels > 0) { Announce("Pressure"); dimOutP = ncdf_out.add_dim("p", nPressureLevels); varOutP = ncdf_out.add_var("p", ncDouble, dimOutP); varOutP->set_cur((long)0); varOutP->put(&(vecPressureLevels[0]), nPressureLevels); } // Output height array NcDim * dimOutZ = NULL; NcVar * varOutZ = NULL; if (nHeightLevels > 0) { Announce("Height"); dimOutZ = ncdf_out.add_dim("z", nHeightLevels); varOutZ = ncdf_out.add_var("z", ncDouble, dimOutZ); varOutZ->set_cur((long)0); varOutZ->put(&(vecHeightLevels[0]), nHeightLevels); } // Output latitude and longitude array Announce("Latitude"); NcDim * dimOutLat = ncdf_out.add_dim("lat", nLat); NcVar * varOutLat = ncdf_out.add_var("lat", ncDouble, dimOutLat); varOutLat->set_cur((long)0); varOutLat->put(&(dLat[0]), nLat); CopyNcVarAttributes(varLat, varOutLat); Announce("Longitude"); NcDim * dimOutLon = ncdf_out.add_dim("lon", nLon); NcVar * varOutLon = ncdf_out.add_var("lon", ncDouble, dimOutLon); varOutLon->set_cur((long)0); varOutLon->put(&(dLon[0]), nLon); CopyNcVarAttributes(varLon, varOutLon); // Output topography Announce("Topography"); NcVar * varOutZs = ncdf_out.add_var( "Zs", ncDouble, dimOutLat, dimOutLon); varOutZs->set_cur((long)0, (long)0); varOutZs->put(&(dZs[0][0]), nLat, nLon); AnnounceEndBlock("Done"); // Done AnnounceEndBlock("Done"); // Load all variables Announce("Loading variables"); std::vector<NcVar *> vecNcVar; for (int v = 0; v < vecVariableStrings.size(); v++) { vecNcVar.push_back(ncdf_in.get_var(vecVariableStrings[v].c_str())); if (vecNcVar[v] == NULL) { _EXCEPTION1("Unable to load variable \"%s\" from file", vecVariableStrings[v].c_str()); } } // Physical constants Announce("Initializing thermodynamic variables"); NcAtt * attEarthRadius = ncdf_in.get_att("earth_radius"); double dEarthRadius = attEarthRadius->as_double(0); NcAtt * attRd = ncdf_in.get_att("Rd"); double dRd = attRd->as_double(0); NcAtt * attCp = ncdf_in.get_att("Cp"); double dCp = attCp->as_double(0); double dGamma = dCp / (dCp - dRd); NcAtt * attP0 = ncdf_in.get_att("P0"); double dP0 = attP0->as_double(0); double dPressureScaling = dP0 * std::pow(dRd / dP0, dGamma); NcAtt * attZtop = ncdf_in.get_att("Ztop"); double dZtop = attZtop->as_double(0); // Input data DataArray3D<double> dataIn(nLev, nLat, nLon); DataArray3D<double> dataInt(nILev, nLat, nLon); // Output data DataArray2D<double> dataOut(nLat, nLon); // Pressure in column DataArray1D<double> dataColumnP(nLev); // Height in column DataArray1D<double> dataColumnZ(nLev); DataArray1D<double> dataColumnIZ(nILev); // Column weights DataArray1D<double> dW(nLev); DataArray1D<double> dIW(nILev); // Loop through all times, pressure levels and variables AnnounceStartBlock("Interpolating"); // Add energy variable NcVar * varEnergy; if (fExtractTotalEnergy) { varEnergy = ncdf_out.add_var("TE", ncDouble, dimOutTime); } // Create output pressure variables std::vector<NcVar *> vecOutNcVarP; if (nPressureLevels > 0) { for (int v = 0; v < vecVariableStrings.size(); v++) { vecOutNcVarP.push_back( ncdf_out.add_var( vecVariableStrings[v].c_str(), ncDouble, dimOutTime, dimOutP, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarP[v]); } } // Create output height variables std::vector<NcVar *> vecOutNcVarZ; if (nHeightLevels > 0) { for (int v = 0; v < vecVariableStrings.size(); v++) { std::string strVarName = vecVariableStrings[v]; if (nPressureLevels > 0) { strVarName += "z"; } vecOutNcVarZ.push_back( ncdf_out.add_var( strVarName.c_str(), ncDouble, dimOutTime, dimOutZ, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarZ[v]); } } // Create output surface variable std::vector<NcVar *> vecOutNcVarS; if (fExtractSurface) { for (int v = 0; v < vecVariableStrings.size(); v++) { std::string strVarName = vecVariableStrings[v]; strVarName += "S"; vecOutNcVarS.push_back( ncdf_out.add_var( strVarName.c_str(), ncDouble, dimOutTime, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarS[v]); } } // Loop over all times for (int t = 0; t < nTime; t++) { char szAnnounce[256]; sprintf(szAnnounce, "Time %i", t); AnnounceStartBlock(szAnnounce); // Rho DataArray3D<double> dataRho(nLev, nLat, nLon); NcVar * varRho = ncdf_in.get_var("Rho"); if (varRho == NULL) { _EXCEPTIONT("Unable to load variable \"Rho\" from file"); } varRho->set_cur(t, 0, 0, 0); varRho->get(&(dataRho[0][0][0]), 1, nLev, nLat, nLon); // Pressure DataArray3D<double> dataP(nLev, nLat, nLon); if (nPressureLevels != 0) { NcVar * varP = ncdf_in.get_var("P"); if (varP == NULL) { _EXCEPTIONT("Unable to load variable \"P\" from file"); } varP->set_cur(t, 0, 0, 0); varP->get(&(dataP[0][0][0]), 1, nLev, nLat, nLon); } /* // Populate pressure array if (nPressureLevels > 0) { // Calculate pointwise pressure for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataP[k][i][j] = dPressureScaling * exp(log(dataRho[k][i][j] * dataP[k][i][j]) * dGamma); } } } } */ // Height everywhere DataArray3D<double> dataZ(nLev, nLat, nLon); DataArray3D<double> dataIZ; if (nILev != 0) { dataIZ.Allocate(nILev, nLat, nLon); } // Populate height array if ((nHeightLevels > 0) || (fGeopotentialHeight)) { for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataZ[k][i][j] = dZs[i][j] + dLev[k] * (dZtop - dZs[i][j]); } } } for (int k = 0; k < nILev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataIZ[k][i][j] = dZs[i][j] + dILev[k] * (dZtop - dZs[i][j]); } } } } // Loop through all pressure levels and variables for (int v = 0; v < vecNcVar.size(); v++) { bool fOnInterfaces = false; // Load in the data array vecNcVar[v]->set_cur(t, 0, 0, 0); if (vecNcVar[v]->get_dim(1)->size() == nLev) { vecNcVar[v]->get(&(dataIn[0][0][0]), 1, nLev, nLat, nLon); Announce("%s (n)", vecVariableStrings[v].c_str()); } else if (vecNcVar[v]->get_dim(1)->size() == nILev) { vecNcVar[v]->get(&(dataInt[0][0][0]), 1, nILev, nLat, nLon); fOnInterfaces = true; Announce("%s (i)", vecVariableStrings[v].c_str()); } else { _EXCEPTION1("Variable \"%s\" has invalid level dimension", vecVariableStrings[v].c_str()); } // At the physical surface if (fExtractSurface) { if (fOnInterfaces) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataOut[i][j] = dataInt[0][i][j]; } } } else { int kBegin = 0; int kEnd = 3; PolynomialInterp::LagrangianPolynomialCoeffs( 3, dLev, dW, 0.0); // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } } } } // Write variable vecOutNcVarS[v]->set_cur(t, 0, 0); vecOutNcVarS[v]->put(&(dataOut[0][0]), 1, nLat, nLon); } // Loop through all pressure levels for (int p = 0; p < nPressureLevels; p++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Store column pressure for (int k = 0; k < nLev; k++) { dataColumnP[k] = dataP[k][i][j]; } // Find weights int kBegin = 0; int kEnd = 0; // On a pressure surface InterpolationWeightsLinear( vecPressureLevels[p], dataColumnP, kBegin, kEnd, dW); // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } } } // Write variable vecOutNcVarP[v]->set_cur(t, p, 0, 0); vecOutNcVarP[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } // Loop through all height levels for (int z = 0; z < nHeightLevels; z++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Find weights int kBegin = 0; int kEnd = 0; // Interpolate from levels to z surfaces if (!fOnInterfaces) { for (int k = 0; k < nLev; k++) { dataColumnZ[k] = dataZ[k][i][j]; } InterpolationWeightsLinear( vecHeightLevels[z], dataColumnZ, kBegin, kEnd, dW); dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } // Interpolate from interfaces to z surfaces } else { for (int k = 0; k < nILev; k++) { dataColumnIZ[k] = dataIZ[k][i][j]; } InterpolationWeightsLinear( vecHeightLevels[z], dataColumnIZ, kBegin, kEnd, dIW); dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dIW[k] * dataInt[k][i][j]; } } } } // Write variable vecOutNcVarZ[v]->set_cur(t, z, 0, 0); vecOutNcVarZ[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } } // Output geopotential height if (fGeopotentialHeight) { Announce("Geopotential height"); // Output variables NcVar * varOutZ; NcVar * varOutZs; if (nPressureLevels > 0) { varOutZ = ncdf_out.add_var( "PHIZ", ncDouble, dimOutTime, dimOutP, dimOutLat, dimOutLon); } if (fExtractSurface) { varOutZs = ncdf_out.add_var( "PHIZS", ncDouble, dimOutTime, dimOutLat, dimOutLon); } // Interpolate onto pressure levels for (int p = 0; p < nPressureLevels; p++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { int kBegin = 0; int kEnd = 0; for (int k = 0; k < nLev; k++) { dataColumnP[k] = dataP[k][i][j]; } InterpolationWeightsLinear( vecPressureLevels[p], dataColumnP, kBegin, kEnd, dW); // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataZ[k][i][j]; } } } // Write variable varOutZ->set_cur(t, p, 0, 0); varOutZ->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } // Interpolate onto the physical surface if (fExtractSurface) { int kBegin = 0; int kEnd = 3; PolynomialInterp::LagrangianPolynomialCoeffs( 3, dLev, dW, 0.0); // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataZ[k][i][j]; } } } // Write variable varOutZs->set_cur(t, 0, 0); varOutZs->put(&(dataOut[0][0]), 1, nLat, nLon); } } // Extract total energy if (fExtractTotalEnergy) { Announce("Total Energy"); // Zonal velocity DataArray3D<double> dataU(nLev, nLat, nLon); NcVar * varU = ncdf_in.get_var("U"); varU->set_cur(t, 0, 0, 0); varU->get(&(dataU[0][0][0]), 1, nLev, nLat, nLon); // Meridional velocity DataArray3D<double> dataV(nLev, nLat, nLon); NcVar * varV = ncdf_in.get_var("V"); varV->set_cur(t, 0, 0, 0); varV->get(&(dataV[0][0][0]), 1, nLev, nLat, nLon); // Vertical velocity DataArray3D<double> dataW(nLev, nLat, nLon); NcVar * varW = ncdf_in.get_var("W"); varW->set_cur(t, 0, 0, 0); varW->get(&(dataW[0][0][0]), 1, nLev, nLat, nLon); // Calculate total energy double dTotalEnergy = 0.0; double dElementRefArea = dEarthRadius * dEarthRadius * M_PI / static_cast<double>(nLat) * 2.0 * M_PI / static_cast<double>(nLon); for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { double dKineticEnergy = 0.5 * dataRho[k][i][j] * ( dataU[k][i][j] * dataU[k][i][j] + dataV[k][i][j] * dataV[k][i][j] + dataW[k][i][j] * dataW[k][i][j]); double dInternalEnergy = dataP[k][i][j] / (dGamma - 1.0); dTotalEnergy += (dKineticEnergy + dInternalEnergy) * std::cos(M_PI * dLat[i] / 180.0) * dElementRefArea * (dZtop - dZs[i][j]) / static_cast<double>(nLev); } } } // Put total energy into file varEnergy->set_cur(t); varEnergy->put(&dTotalEnergy, 1); } AnnounceEndBlock("Done"); } AnnounceEndBlock("Done"); } catch(Exception & e) { Announce(e.ToString().c_str()); } // Finalize MPI MPI_Finalize(); }
/* * Actually save the powder pattern to file */ void savePowderPattern(cGlobal *global, int detIndex, int powderClass) { // Dereference common variables cPixelDetectorCommon *detector = &(global->detector[detIndex]); long nframes = detector->nPowderFrames[powderClass]; // Define buffer variables double *powderBuffer; double *powderSquaredBuffer; double *powderSigmaBuffer; double *bufferPeaks; char sBuffer[1024]; /* * Filename */ char filename[1024]; char filenamebase[1024]; sprintf(filenamebase,"r%04u-detector%ld-class%d", global->runNumber, global->detector[detIndex].detectorID, powderClass); sprintf(filename,"%s-sum.h5",filenamebase); printf("%s\n",filename); /* * Mess of stuff for writing the compound HDF5 file */ #ifdef H5F_ACC_SWMR_WRITE pthread_mutex_lock(&global->swmr_mutex); #endif hid_t fh, gh, sh, dh; /* File, group, dataspace and data handles */ //herr_t r; hsize_t size[2]; //hsize_t max_size[2]; hid_t h5compression; // Create file fh = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if ( fh < 0 ) { ERROR("Couldn't create HDF5 file: %s\n", filename); } gh = H5Gcreate(fh, "data", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if ( gh < 0 ) { ERROR("Couldn't create HDF5 group\n"); H5Fclose(fh); } // Setting compression level if (global->h5compress) { h5compression = H5Pcreate(H5P_DATASET_CREATE); } else { h5compression = H5P_DEFAULT; } FOREACH_DATAFORMAT_T(i_f, cDataVersion::DATA_FORMATS) { if (isBitOptionSet(global->detector[detIndex].powderFormat, *i_f)) { cDataVersion dataV(NULL, &global->detector[detIndex], global->detector[detIndex].powderVersion, *i_f); while (dataV.next()) { if (*i_f != cDataVersion::DATA_FORMAT_RADIAL_AVERAGE) { // size for 2D data size[0] = dataV.pix_ny; size[1] = dataV.pix_nx; sh = H5Screate_simple(2, size, NULL); // Compression for 1D if (global->h5compress) { H5Pset_chunk(h5compression, 2, size); H5Pset_deflate(h5compression, global->h5compress); // Compression levels are 0 (none) to 9 (max) } } else { // size for 1D data (radial average) size[0] = dataV.pix_nn; size[1] = 0; sh = H5Screate_simple(1, size, NULL); // Compression for 1D h5compression = H5P_DEFAULT; } double *powder = dataV.getPowder(powderClass); double *powder_squared = dataV.getPowderSquared(powderClass); long *powder_counter = dataV.getPowderCounter(powderClass); pthread_mutex_t *mutex = dataV.getPowderMutex(powderClass); // Copy powder pattern to buffer powderBuffer = (double*) calloc(dataV.pix_nn, sizeof(double)); if (global->threadSafetyLevel > 0) pthread_mutex_lock(mutex); memcpy(powderBuffer, powder, dataV.pix_nn*sizeof(double)); if (global->threadSafetyLevel > 0) pthread_mutex_unlock(mutex); // Masked powders require a per-pixel correction if(global->detector[detIndex].savePowderMasked != 0 && powder_counter != NULL) { for (long i=0; i<dataV.pix_nn; i++) { if(powder_counter[i] != 0) powderBuffer[i] /= powder_counter[i]; else powderBuffer[i] = 0; } } // Write powder to dataset dh = H5Dcreate(gh, dataV.name, H5T_NATIVE_DOUBLE, sh, H5P_DEFAULT, h5compression, H5P_DEFAULT); if (dh < 0) ERROR("Could not create dataset.\n"); H5Dwrite(dh, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, powderBuffer); H5Dclose(dh); // Fluctuations (sigma) powderSquaredBuffer = (double*) calloc(dataV.pix_nn, sizeof(double)); powderSigmaBuffer = (double*) calloc(dataV.pix_nn, sizeof(double)); if (global->threadSafetyLevel > 0) pthread_mutex_lock(mutex); memcpy(powderSquaredBuffer, powder_squared, dataV.pix_nn*sizeof(double)); if (global->threadSafetyLevel > 0) pthread_mutex_unlock(mutex); // Masked powders require a per-pixel correction if(global->detector[detIndex].savePowderMasked != 0 && powder_counter != NULL) { for (long i=0; i<dataV.pix_nn; i++) { if(powder_counter[i] != 0) powderSigmaBuffer[i] = sqrt(powderSquaredBuffer[i]/powder_counter[i] - powderBuffer[i]*powderBuffer[i]); } } else { for (long i=0; i<dataV.pix_nn; i++) { powderSigmaBuffer[i] = sqrt(powderSquaredBuffer[i]/nframes - (powderBuffer[i]/nframes)*(powderBuffer[i]/nframes)); } } // Write to data set sprintf(sBuffer,"%s_sigma",dataV.name); dh = H5Dcreate(gh, sBuffer, H5T_NATIVE_DOUBLE, sh, H5P_DEFAULT, h5compression, H5P_DEFAULT); if (dh < 0) ERROR("Could not create dataset.\n"); H5Dwrite(dh, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, powderSigmaBuffer); H5Dclose(dh); // Soft link if main data set if (dataV.isMainDataset) { // Create symbolic link if this is the main dataset sprintf(sBuffer,"/data/%s",dataV.name); H5Lcreate_soft(sBuffer, fh, "/data/data",0,0); H5Lcreate_soft(sBuffer, fh, "/data/correcteddata",0,0); } free(powderBuffer); free(powderSquaredBuffer); free(powderSigmaBuffer); H5Sclose(sh); } } } // Peak powder size[0] = detector->pix_ny; size[1] = detector->pix_nx; sh = H5Screate_simple(2, size, NULL); bufferPeaks = (double*) calloc(detector->pix_nn, sizeof(double)); pthread_mutex_lock(&detector->powderPeaks_mutex[powderClass]); memcpy(bufferPeaks, detector->powderPeaks[powderClass], detector->pix_nn*sizeof(double)); pthread_mutex_unlock(&detector->powderPeaks_mutex[powderClass]); dh = H5Dcreate(gh, "peakpowder", H5T_NATIVE_DOUBLE, sh, H5P_DEFAULT, h5compression, H5P_DEFAULT); if (dh < 0) ERROR("Could not create dataset.\n"); H5Dwrite(dh, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, bufferPeaks); H5Dclose(dh); H5Sclose(sh); free(bufferPeaks); // Save frame count size[0] = 1; sh = H5Screate_simple(1, size, NULL ); dh = H5Dcreate(gh, "nframes", H5T_NATIVE_LONG, sh, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if (dh < 0) ERROR("Could not create dataset.\n"); H5Dwrite(dh, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &detector->nPowderFrames[powderClass] ); H5Dclose(dh); H5Sclose(sh); // Clean up stale HDF5 links H5Gclose(gh); int n_ids; hid_t ids[256]; n_ids = H5Fget_obj_ids(fh, H5F_OBJ_ALL, 256, ids); for ( int i=0; i<n_ids; i++ ) { hid_t id; H5I_type_t type; id = ids[i]; type = H5Iget_type(id); if ( type == H5I_GROUP ) H5Gclose(id); if ( type == H5I_DATASET ) H5Dclose(id); if ( type == H5I_DATATYPE ) H5Tclose(id); if ( type == H5I_DATASPACE ) H5Sclose(id); if ( type == H5I_ATTR ) H5Aclose(id); } H5Fclose(fh); #ifdef H5F_ACC_SWMR_WRITE pthread_mutex_unlock(&global->swmr_mutex); #endif /* * Clean up stuff */ for(long i=0; i<global->nPowderClasses; i++) { fflush(global->powderlogfp[i]); fflush(global->framelist[i]); } }