Changeset 3243
- Timestamp:
- 01/06/12 16:30:58 (5 months ago)
- Files:
-
- 1 modified
-
trunk/lib/share/mccode-r.c (modified) (151 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/share/mccode-r.c
r3231 r3243 16 16 * Runtime system for McStas and McXtrace. 17 17 * Embedded within instrument in runtime mode. 18 * Contains SECTIONS: 18 * Contains SECTIONS: 19 19 * MPI handling (sum, send, recv) 20 20 * format definitions … … 82 82 /* Instrument input parameter type handling. */ 83 83 /******************************************************************************* 84 * mcparm_double: extract double value from 's' into 'vptr' 84 * mcparm_double: extract double value from 's' into 'vptr' 85 85 *******************************************************************************/ 86 86 static int … … 99 99 100 100 /******************************************************************************* 101 * mcparminfo_double: display parameter type double 101 * mcparminfo_double: display parameter type double 102 102 *******************************************************************************/ 103 103 static char * … … 108 108 109 109 /******************************************************************************* 110 * mcparmerror_double: display error message when failed extract double 110 * mcparmerror_double: display error message when failed extract double 111 111 *******************************************************************************/ 112 112 static void … … 118 118 119 119 /******************************************************************************* 120 * mcparmprinter_double: convert double to string 120 * mcparmprinter_double: convert double to string 121 121 *******************************************************************************/ 122 122 static void … … 128 128 129 129 /******************************************************************************* 130 * mcparm_int: extract int value from 's' into 'vptr' 130 * mcparm_int: extract int value from 's' into 'vptr' 131 131 *******************************************************************************/ 132 132 static int … … 150 150 151 151 /******************************************************************************* 152 * mcparminfo_int: display parameter type int 152 * mcparminfo_int: display parameter type int 153 153 *******************************************************************************/ 154 154 static char * … … 159 159 160 160 /******************************************************************************* 161 * mcparmerror_int: display error message when failed extract int 161 * mcparmerror_int: display error message when failed extract int 162 162 *******************************************************************************/ 163 163 static void … … 169 169 170 170 /******************************************************************************* 171 * mcparmprinter_int: convert int to string 171 * mcparmprinter_int: convert int to string 172 172 *******************************************************************************/ 173 173 static void … … 179 179 180 180 /******************************************************************************* 181 * mcparm_string: extract char* value from 's' into 'vptr' (copy) 181 * mcparm_string: extract char* value from 's' into 'vptr' (copy) 182 182 *******************************************************************************/ 183 183 static int … … 196 196 197 197 /******************************************************************************* 198 * mcparminfo_string: display parameter type string 198 * mcparminfo_string: display parameter type string 199 199 *******************************************************************************/ 200 200 static char * … … 205 205 206 206 /******************************************************************************* 207 * mcparmerror_string: display error message when failed extract string 207 * mcparmerror_string: display error message when failed extract string 208 208 *******************************************************************************/ 209 209 static void … … 215 215 216 216 /******************************************************************************* 217 * mcparmprinter_string: convert string to string (including esc chars) 217 * mcparmprinter_string: convert string to string (including esc chars) 218 218 *******************************************************************************/ 219 219 static void … … 266 266 267 267 /******************************************************************************* 268 * mcestimate_error: compute sigma from N,p,p2 in Gaussian large numbers approx 268 * mcestimate_error: compute sigma from N,p,p2 in Gaussian large numbers approx 269 269 *******************************************************************************/ 270 270 double mcestimate_error(double N, double p1, double p2) … … 281 281 282 282 double (*mcestimate_error_p) 283 (double V2, double psum, double p2sum)=mcestimate_error; 283 (double V2, double psum, double p2sum)=mcestimate_error; 284 284 285 285 /* SECTION: MPI handling ==================================================== */ … … 296 296 int mc_MPI_Sum(double *sbuf, long count) 297 297 { 298 298 299 299 if (!sbuf || count <= 0) return(MPI_ERR_COUNT); 300 300 else { … … 305 305 int i=0; 306 306 while (offset < count) { 307 if (!length || offset+length > count-1) length=count-offset; 307 if (!length || offset+length > count-1) length=count-offset; 308 308 else length=MPI_REDUCE_BLOCKSIZE; 309 MPI_Allreduce((double*)(sbuf+offset), (double*)(rbuf+offset), 309 MPI_Allreduce((double*)(sbuf+offset), (double*)(rbuf+offset), 310 310 length, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); 311 311 offset += length; 312 312 } 313 313 314 314 for (i=0; i<count; i++) sbuf[i] = rbuf[i]; 315 315 } … … 320 320 * mc_MPI_Send: Send array to MPI node by blocks to avoid buffer limit 321 321 *******************************************************************************/ 322 int mc_MPI_Send(void *sbuf, 322 int mc_MPI_Send(void *sbuf, 323 323 long count, MPI_Datatype dtype, 324 324 int dest) … … 328 328 int tag=1; 329 329 int length=MPI_REDUCE_BLOCKSIZE; /* defined in mcstas.h */ 330 330 331 331 if (!sbuf || count <= 0) return(MPI_ERR_COUNT); 332 332 MPI_Type_size(dtype, &dsize); 333 333 334 334 while (offset < count) { 335 if (offset+length > count-1) length=count-offset; 335 if (offset+length > count-1) length=count-offset; 336 336 else length=MPI_REDUCE_BLOCKSIZE; 337 337 MPI_Send((void*)(sbuf+offset*dsize), length, dtype, dest, tag++, MPI_COMM_WORLD); … … 346 346 * the buffer must have been allocated previously. 347 347 *******************************************************************************/ 348 int mc_MPI_Recv(void *sbuf, 348 int mc_MPI_Recv(void *sbuf, 349 349 long count, MPI_Datatype dtype, 350 350 int source) … … 354 354 int tag=1; 355 355 int length=MPI_REDUCE_BLOCKSIZE; /* defined in mcstas.h */ 356 356 357 357 if (!sbuf || count <= 0) return(MPI_ERR_COUNT); 358 358 MPI_Type_size(dtype, &dsize); 359 359 360 360 while (offset < count) { 361 if (offset+length > count-1) length=count-offset; 361 if (offset+length > count-1) length=count-offset; 362 362 else length=MPI_REDUCE_BLOCKSIZE; 363 MPI_Recv((void*)(sbuf+offset*dsize), length, dtype, source, tag++, 363 MPI_Recv((void*)(sbuf+offset*dsize), length, dtype, source, tag++, 364 364 MPI_COMM_WORLD, MPI_STATUS_IGNORE); 365 365 offset += length; … … 385 385 *******************************************************************************/ 386 386 387 /* {Name, Extension, Header, Footer, 387 /* {Name, Extension, Header, Footer, 388 388 BeginSection, EndSection, AssignTag; 389 389 BeginData, EndData; … … 1013 1013 int dirlen=0; 1014 1014 char *mem =NULL; 1015 1015 1016 1016 dirlen = mcdirname ? strlen(mcdirname) : 0; 1017 1017 mem = malloc(dirlen + strlen(name) + CHAR_BUF_LENGTH); … … 1020 1020 } 1021 1021 strcpy(mem, ""); 1022 1022 1023 1023 /* prepend directory name to path if name does not contain a path */ 1024 1024 if (dirlen > 0 && !strchr(name, MC_PATHSEP_C)) { … … 1026 1026 strcat(mem, MC_PATHSEP_S); 1027 1027 } /* dirlen */ 1028 1028 1029 1029 strcat(mem, name); 1030 1030 if (!strchr(name, '.') && ext && strlen(ext)) … … 1052 1052 fprintf(stderr, "Warning: could not open output file '%s' in mode '%s' (mcnew_file)\n", mem, mode); 1053 1053 else { 1054 if (!mcopenedfiles || 1054 if (!mcopenedfiles || 1055 1055 (mcopenedfiles && mcopenedfiles_size <= strlen(mcopenedfiles)+strlen(mem))) { 1056 1056 mcopenedfiles_size+=CHAR_BUF_LENGTH; … … 1059 1059 else 1060 1060 mcopenedfiles = realloc(mcopenedfiles, mcopenedfiles_size); 1061 } 1061 } 1062 1062 strcat(mcopenedfiles, " "); 1063 1063 strcat(mcopenedfiles, mem); 1064 1064 } 1065 1065 free(mem); 1066 1066 1067 1067 return file; 1068 1068 } /* mcnew_file */ … … 1123 1123 1124 1124 /******************************************************************************* 1125 * pfprintf: just as fprintf with positional arguments %N$t, 1125 * pfprintf: just as fprintf with positional arguments %N$t, 1126 1126 * but with (char *)fmt_args being the list of arg type 't'. 1127 1127 * Needed as the vfprintf is not correctly handled on some platforms. … … 1169 1169 { /* found a dollar following a percent and a digit after percent */ 1170 1170 char this_arg_chr[10]; 1171 1171 1172 1172 1173 1173 /* extract positional argument index %*$ in fmt */ … … 1193 1193 } else if (strchr(printf_formats,tmp[1])) { 1194 1194 fmt_pos = arg_posB[this_arg]+1; /* found %s */ 1195 } else { 1195 } else { 1196 1196 return(-fprintf(stderr,"pfprintf: must use only positional arguments (%s).\n", arg_posB[this_arg])); 1197 1197 } … … 1294 1294 char date[CHAR_BUF_LENGTH]; /* date as a string */ 1295 1295 char valid_parent[VALID_NAME_LENGTH]; /* who generates that: the simulation or mcstas */ 1296 1296 1297 1297 if (mcdisable_output_files) return(-1); 1298 1298 if (!detector.file_handle && !strstr(detector.format.Name,"NeXus")) return(-1); 1299 1299 if (strcmp(part,"header") && strstr(detector.format.Name, "no header")) return (-2); 1300 1300 if (strcmp(part,"footer") && strstr(detector.format.Name, "no footer")) return (-3); 1301 1301 1302 1302 /* initiate date and format string ======================================== */ 1303 1303 1304 1304 date_l = detector.date_l; /* use current write time (from import) by default */ 1305 1305 strncpy(date, detector.date, CHAR_BUF_LENGTH); … … 1309 1309 else { 1310 1310 HeadFoot = detector.format.Header; /* SIM header has simulation start time */ 1311 if (detector.file_handle == mcsiminfo_file 1311 if (detector.file_handle == mcsiminfo_file 1312 1312 && !strcmp(detector.filename, mcsiminfo_name)) { 1313 1313 date_l = mcstartdate; … … 1318 1318 } 1319 1319 1320 mcvalid_name(valid_parent, 1320 mcvalid_name(valid_parent, 1321 1321 strlen(detector.filename) && detector.file_handle!=mcsiminfo_file ? 1322 1322 detector.filename : detector.simulation, VALID_NAME_LENGTH); 1323 1323 1324 1324 /* output header ========================================================== */ 1325 1325 … … 1329 1329 detector.prefix, /* %1$s PRE */ 1330 1330 detector.instrument, /* %2$s SRC */ 1331 strlen(detector.filename) ? 1331 strlen(detector.filename) ? 1332 1332 detector.filename: detector.simulation, /* %3$s FIL */ 1333 1333 detector.format.Name, /* %4$s FMT */ … … 1337 1337 detector.date_l) == NX_ERROR) { /* %8$li DATL */ 1338 1338 fprintf(stderr, "Error: writing NeXus header file %s (mcinfo_header)\n", 1339 strlen(detector.filename) ? 1339 strlen(detector.filename) ? 1340 1340 detector.filename: detector.simulation); 1341 1341 /* close information data set opened by mcnxfile_section */ 1342 1342 return(-1); 1343 } 1343 } 1344 1344 else return(1); 1345 1345 } … … 1349 1349 detector.prefix, /* %1$s PRE */ 1350 1350 detector.instrument, /* %2$s SRC */ 1351 strlen(detector.filename) ? 1351 strlen(detector.filename) ? 1352 1352 detector.filename: detector.simulation, /* %3$s FIL */ 1353 1353 detector.format.Name, /* %4$s FMT */ … … 1379 1379 1380 1380 /* remove quote chars in values =========================================== */ 1381 if (strstr(detector.format.Name, "Scilab") 1382 || strstr(detector.format.Name, "Matlab") 1381 if (strstr(detector.format.Name, "Scilab") 1382 || strstr(detector.format.Name, "Matlab") 1383 1383 || strstr(detector.format.Name, "IDL")) 1384 1384 for(i = 0; i < strlen(value); i++) { … … 1386 1386 if (value[i] == '\n' || value[i] == '\r') value[i] = ';'; 1387 1387 } 1388 1388 1389 1389 /* output tag ============================================================= */ 1390 1390 #ifdef USE_NEXUS … … 1434 1434 else strcpy(valid_parent, "root"); 1435 1435 1436 if (!strcmp(part,"end") && strlen(detector.prefix) >= 2) 1436 if (!strcmp(part,"end") && strlen(detector.prefix) >= 2) 1437 1437 detector.prefix[strlen(detector.prefix)-2]='\0'; /* un-indent prefix */ 1438 1438 1439 1439 /* output section ========================================================= */ 1440 1440 … … 1445 1445 fprintf(stderr, "Error: writing NeXus section %s/%s=NX%s (mcfile_section)\n", parent, section, type); 1446 1446 return(detector); 1447 } 1447 } 1448 1448 } 1449 1449 else … … 1457 1457 valid_parent, /* %6$s VPA */ 1458 1458 level); /* %7$i LVL */ 1459 1459 1460 1460 /* handle prefix++ and write section start ID ============================= */ 1461 1461 … … 1498 1498 if (strlen(Parameters) >= CHAR_BUF_LENGTH-VALID_NAME_LENGTH) break; 1499 1499 } 1500 1500 1501 1501 /* output data ============================================================ */ 1502 1502 mcinfo_tag(detector, name, "Parameters", Parameters); … … 1534 1534 char nxname[CHAR_BUF_LENGTH]; 1535 1535 int length; 1536 if (mcinputtable[i].par == NULL) 1536 if (mcinputtable[i].par == NULL) 1537 1537 strncpy(Parameters, (mcinputtable[i].val ? mcinputtable[i].val : ""), CHAR_BUF_LENGTH); 1538 else 1538 else 1539 1539 (*mcinputtypes[mcinputtable[i].type].printer)(Parameters, mcinputtable[i].par); 1540 1540 sprintf(nxname, "%s", Parameters); … … 1574 1574 snprintf(Parameters, CHAR_BUF_LENGTH, "%ld", mcseed); 1575 1575 mcinfo_tag(detector, instr, "Seed", Parameters); 1576 1576 1577 1577 /* output parameter string ================================================ */ 1578 1578 if (!strstr(detector.format.Name, "McStas")) { 1579 #ifdef USE_NEXUS 1579 #ifdef USE_NEXUS 1580 1580 /* close simulation/information */ 1581 1581 if (strstr(detector.format.Name, "NeXus")) 1582 1582 if (NXclosedata(mcnxHandle) == NX_ERROR) 1583 1583 fprintf(stderr, "Warning: NeXus: could not close data set simulation/information in %s\n", detector.filename); 1584 #endif 1584 #endif 1585 1585 detector = mcfile_section(detector, "begin", instr, "parameters", "parameters", 3); 1586 1586 } 1587 1587 1588 1588 for(i = 0; i < mcnumipar; i++) { 1589 1589 if (mcget_run_num() || (mcinputtable[i].val && strlen(mcinputtable[i].val))) { 1590 if (mcinputtable[i].par == NULL) 1590 if (mcinputtable[i].par == NULL) 1591 1591 strncpy(Parameters, (mcinputtable[i].val ? mcinputtable[i].val : ""), CHAR_BUF_LENGTH); 1592 else 1592 else 1593 1593 (*mcinputtypes[mcinputtable[i].type].printer)(Parameters, mcinputtable[i].par); 1594 if (strstr(detector.format.Name, "McStas")) 1594 if (strstr(detector.format.Name, "McStas")) 1595 1595 fprintf(detector.file_handle, "%sParam: %s=%s\n", detector.prefix, mcinputtable[i].name, Parameters); 1596 1596 else … … 1605 1605 /* in the parameter group, create one SDS per parameter */ 1606 1606 mcnxfile_parameters(mcnxHandle); 1607 1608 /* this can not be included in nexus-lib as it requires mcinputtypes which 1607 1608 /* this can not be included in nexus-lib as it requires mcinputtypes which 1609 1609 is defined only in mccode-r.c (points to function that are defined here) */ 1610 1611 1610 1611 1612 1612 /* re-open the simulation/information dataset */ 1613 1613 if (NXopendata(mcnxHandle, "information") == NX_ERROR) { … … 1616 1616 } 1617 1617 #endif 1618 if (!strstr(detector.format.Name, "McStas")) 1618 if (!strstr(detector.format.Name, "McStas")) 1619 1619 detector = mcfile_section(detector, "end", instr, "parameters", "parameters", 3); 1620 1620 1621 1621 fflush(NULL); 1622 1622 … … 1633 1633 { 1634 1634 char parent[CHAR_BUF_LENGTH]; 1635 1635 1636 1636 if (!detector.m || mcdisable_output_files) return; 1637 1637 … … 1644 1644 if (!detector.file_handle) return; 1645 1645 } 1646 1646 1647 1647 /* parent must be a valid name */ 1648 1648 mcvalid_name(parent, detector.filename, VALID_NAME_LENGTH); 1649 1649 1650 1650 /* output data ============================================================ */ 1651 1651 mcinfo_tag(detector, parent, "type", detector.type); 1652 1652 mcinfo_tag(detector, parent, "Source", mcinstrument_source); 1653 mcinfo_tag(detector, parent, (strstr(detector.format.Name,"McStas") ? 1653 mcinfo_tag(detector, parent, (strstr(detector.format.Name,"McStas") ? 1654 1654 "component" : "parent"), detector.component); 1655 1655 mcinfo_tag(detector, parent, "position", detector.position); 1656 1656 1657 1657 mcinfo_tag(detector, parent, "title", detector.title); 1658 mcinfo_tag(detector, parent, !mcget_run_num() || mcget_run_num() >= mcget_ncount() ? 1658 mcinfo_tag(detector, parent, !mcget_run_num() || mcget_run_num() >= mcget_ncount() ? 1659 1659 "Ncount" : "ratio", detector.ncount); 1660 1660 1661 1661 if (strlen(detector.filename)) { 1662 1662 mcinfo_tag(detector, parent, "filename", detector.filename); … … 1665 1665 1666 1666 mcinfo_tag(detector, parent, "statistics", detector.statistics); 1667 mcinfo_tag(detector, parent, strstr(detector.format.Name, "NeXus") ? 1667 mcinfo_tag(detector, parent, strstr(detector.format.Name, "NeXus") ? 1668 1668 "Signal" : "signal", detector.signal); 1669 1669 mcinfo_tag(detector, parent, "values", detector.values); … … 1671 1671 if (detector.rank >= 1 || detector.rank == -1) 1672 1672 { 1673 mcinfo_tag(detector, parent, (strstr(detector.format.Name," scan ") ? 1673 mcinfo_tag(detector, parent, (strstr(detector.format.Name," scan ") ? 1674 1674 "xvars" : "xvar"), detector.xvar); 1675 mcinfo_tag(detector, parent, (strstr(detector.format.Name," scan ") ? 1675 mcinfo_tag(detector, parent, (strstr(detector.format.Name," scan ") ? 1676 1676 "yvars" : "yvar"), detector.yvar); 1677 1677 mcinfo_tag(detector, parent, "xlabel", detector.xlabel); … … 1683 1683 } 1684 1684 1685 mcinfo_tag(detector, parent, abs(detector.rank)==1 && strstr(detector.format.Name, "McStas") ? 1685 mcinfo_tag(detector, parent, abs(detector.rank)==1 && strstr(detector.format.Name, "McStas") ? 1686 1686 "xlimits" : "xylimits", detector.limits); 1687 1687 mcinfo_tag(detector, parent, "variables", detector.rank == -1 ? 1688 1688 detector.zvar : detector.variables); 1689 1689 1690 1690 if (mcDetectorCustomHeader && strlen(mcDetectorCustomHeader)) { 1691 1691 mcinfo_tag(detector, parent, "custom", mcDetectorCustomHeader); 1692 } 1692 } 1693 1693 1694 1694 fflush(NULL); … … 1718 1718 char istransposed=0; 1719 1719 char c[CHAR_BUF_LENGTH]; /* temp var for signal label */ 1720 1720 1721 1721 MCDETECTOR detector; 1722 1722 1723 1723 /* build MCDETECTOR structure ============================================= */ 1724 1724 /* make sure we do not have NULL for char fields */ 1725 1725 1726 1726 /* these also apply to simfile */ 1727 1727 strncpy (detector.filename, filename ? filename : "", CHAR_BUF_LENGTH); … … 1732 1732 strcat(detector.filename, format.Extension); 1733 1733 } 1734 strncpy (detector.component, component ? component : "McStas component", CHAR_BUF_LENGTH); 1734 strncpy (detector.component, component ? component : "McStas component", CHAR_BUF_LENGTH); 1735 1735 snprintf(detector.simulation, CHAR_BUF_LENGTH, "%s%s%s", 1736 1736 mcdirname && strlen(mcdirname) ? mcdirname : ".", MC_PATHSEP_S, mcsiminfo_name); 1737 1737 detector.format=format; 1738 1738 1739 1739 /* set prefix: # for McStas data files, VRML and Python */ 1740 strcpy(detector.prefix, 1741 (strstr(format.Name, "McStas") && (strlen(detector.filename)) ? 1740 strcpy(detector.prefix, 1741 (strstr(format.Name, "McStas") && (strlen(detector.filename)) ? 1742 1742 "# " : "")); 1743 1743 1744 1744 snprintf(detector.instrument, CHAR_BUF_LENGTH, "%s (%s)", mcinstrument_name, mcinstrument_source); 1745 1745 snprintf(detector.user, CHAR_BUF_LENGTH, "%s on %s", … … 1751 1751 if (strlen(detector.date)) detector.date[strlen(detector.date)-1] = '\0'; /* remove last \n in date */ 1752 1752 detector.date_l = date_l; 1753 1753 1754 1754 if (!mcget_run_num() || mcget_run_num() >= mcget_ncount()) 1755 1755 snprintf(detector.ncount, CHAR_BUF_LENGTH, "%g", (double)mcget_ncount()); 1756 else 1756 else 1757 1757 snprintf(detector.ncount, CHAR_BUF_LENGTH, "%g/%g", (double)mcget_run_num(), (double)mcget_ncount()); 1758 1758 1759 1759 detector.p0 = p0; detector.p0_orig=p0; 1760 1760 detector.p1 = p1; detector.p1_orig=p1; 1761 1761 detector.p2 = p2; detector.p2_orig=p2; 1762 1762 detector.file_handle= filename ? NULL : mcsiminfo_file; 1763 1763 1764 1764 /* handle transposition */ 1765 1765 if (!strstr(format.Name, "NeXus")) { … … 1770 1770 long i=m; m=abs(n); n=abs(i); p=abs(p); 1771 1771 } 1772 } 1772 } 1773 1773 m=abs(m); n=abs(n); p=abs(p); /* make sure dimensions are positive */ 1774 1774 detector.istransposed = istransposed; 1775 1775 1776 1776 /* determine detector rank (dimensionality) */ 1777 1777 if (!m || !n || !p || !p1) detector.rank = 4; /* invalid: exit with m=0 filename="" */ … … 1781 1781 else if (p == 1) detector.rank = 2; /* 2D */ 1782 1782 else detector.rank = 3; /* 3D */ 1783 1783 1784 1784 /* from rank, set type */ 1785 1785 switch (detector.rank) { … … 1791 1791 default: m=0; strcpy(detector.type, ""); strcpy(detector.filename, "");/* invalid */ 1792 1792 } 1793 1793 1794 1794 detector.m = m; 1795 1795 detector.n = n; … … 1807 1807 detector.centerY = 0; 1808 1808 detector.halfwidthY = 0; 1809 1809 1810 1810 /* these only apply to detector files ===================================== */ 1811 1811 … … 1831 1831 else 1832 1832 snprintf(detector.variables, CHAR_BUF_LENGTH, "%s %s_err N", c, c); 1833 1833 1834 1834 /* limits */ 1835 1835 detector.xmin = x1; … … 1845 1845 else 1846 1846 snprintf(detector.limits, CHAR_BUF_LENGTH, "%g %g %g %g %g %g", x1, x2, y1, y2, z1, z2); 1847 1848 if (!m || !n || !p) { 1847 1848 if (!m || !n || !p) { 1849 1849 return(detector); 1850 1850 } 1851 1851 1852 1852 /* if MPI and nodes_nb > 1: reduce data sets when using MPI =============== */ 1853 1853 /* not for scan steps/multiarray (only processed by root */ … … 1858 1858 if (p1) mc_MPI_Sum(p1, abs(m*n*p)); 1859 1859 if (p2) mc_MPI_Sum(p2, abs(m*n*p)); 1860 1860 1861 1861 if (!p0) { /* additive signal must be then divided by the number of nodes */ 1862 1862 int i; … … 1876 1876 double Nsum=0; 1877 1877 double P2sum=0; 1878 1878 1879 1879 double sum_xz = 0; 1880 1880 double sum_yz = 0; … … 1888 1888 char israw = (strstr(detector.format.Name," raw") != NULL); 1889 1889 double *this_p1=NULL; /* new 1D McStas array [x I E N]. Freed after writing data */ 1890 1890 1891 1891 /* if McStas/PGPLOT and rank==1 we create a new m*4 data block=[x I E N] */ 1892 1892 if (detector.rank == 1 && strstr(detector.format.Name,"McStas")) { … … 1895 1895 exit(-fprintf(stderr, "Error: Out of memory creating %li 1D McStas data set for file '%s' (mcdetector_import)\n", detector.m*detector.n*detector.p*4*sizeof(double*), detector.filename)); 1896 1896 } 1897 1897 1898 1898 max_z = min_z = p1[0]; 1899 1899 1900 1900 for(j = 0; j < n*p; j++) 1901 1901 { … … 1912 1912 E = p2 ? p2[index] : 0; 1913 1913 if (p2 && !israw) p2[index] = (*mcestimate_error_p)(p0[i],p1[i],p2[i]); /* set sigma */ 1914 1914 1915 1915 /* compute stats integrals */ 1916 1916 sum_xz += x*z; … … 1926 1926 Nsum += N; 1927 1927 P2sum += E; 1928 1928 1929 1929 if (isnan(z) || isnan(E) || isnan(N)) hasnan=1; 1930 1930 if (isinf(z) || isinf(E) || isinf(N)) hasinf=1; 1931 1931 1932 1932 if (detector.rank == 1 && this_p1 && strstr(detector.format.Name,"McStas")) { 1933 1933 /* fill-in 1D McStas array [x I E N] */ 1934 this_p1[index*4] = x; 1934 this_p1[index*4] = x; 1935 1935 this_p1[index*4+1] = z; 1936 1936 this_p1[index*4+2] = p2 ? p2[index] : 0; … … 1939 1939 } 1940 1940 } /* for j */ 1941 1941 1942 1942 /* compute 1st and 2nd moments */ 1943 1943 if (sum_z && n*m*p) … … 1960 1960 detector.centerY = fmon_y; 1961 1961 detector.halfwidthY= smon_y; 1962 1962 1963 1963 /* if McStas/PGPLOT and rank==1 replace p1 with new m*4 1D McStas and clear others */ 1964 1964 if (detector.rank == 1 && this_p1 && strstr(detector.format.Name,"McStas")) { 1965 1965 detector.p1 = this_p1; 1966 detector.n=detector.m; detector.m = 4; 1966 detector.n=detector.m; detector.m = 4; 1967 1967 detector.p0 = NULL; 1968 1968 detector.p2 = NULL; 1969 1969 detector.istransposed = 1; 1970 1970 } 1971 1971 1972 1972 if (n*m*p > 1) 1973 1973 sprintf(detector.signal, "Min=%g; Max=%g; Mean=%g;", detector.min, detector.max, detector.mean); 1974 else 1974 else 1975 1975 strcpy(detector.signal, ""); 1976 1976 sprintf(detector.values, "%g %g %g", detector.intensity, detector.error, detector.events); 1977 1977 1978 1978 switch (detector.rank) { 1979 1979 case 0: strcpy(detector.statistics, ""); break; 1980 case 1: snprintf(detector.statistics, CHAR_BUF_LENGTH, "X0=%g; dX=%g;", 1980 case 1: snprintf(detector.statistics, CHAR_BUF_LENGTH, "X0=%g; dX=%g;", 1981 1981 detector.centerX, detector.halfwidthX); break; 1982 1982 case 2: 1983 case 3: snprintf(detector.statistics, CHAR_BUF_LENGTH, "X0=%g; dX=%g; Y0=%g; dY=%g;", 1984 detector.centerX, detector.halfwidthX, detector.centerY, detector.halfwidthY); 1983 case 3: snprintf(detector.statistics, CHAR_BUF_LENGTH, "X0=%g; dX=%g; Y0=%g; dY=%g;", 1984 detector.centerX, detector.halfwidthX, detector.centerY, detector.halfwidthY); 1985 1985 break; 1986 1986 default: strcpy(detector.statistics, ""); … … 1993 1993 } 1994 1994 #endif 1995 1995 1996 1996 /* output "Detector:" line ================================================ */ 1997 /* when this is a detector written by a component (not the SAVE from instrument), 1997 /* when this is a detector written by a component (not the SAVE from instrument), 1998 1998 not a multiarray nor event lists */ 1999 1999 if (detector.rank == -1 || strstr(format.Name," list ")) return(detector); 2000 2000 2001 2001 if (!strcmp(detector.component, mcinstrument_name)) { 2002 2002 if (strlen(detector.filename)) /* we name it from its filename, or from its title */ … … 2006 2006 } else 2007 2007 strncpy(c, detector.component, CHAR_BUF_LENGTH); /* usual detectors written by components */ 2008 2008 2009 2009 printf("Detector: %s_I=%g %s_ERR=%g %s_N=%g", 2010 c, detector.intensity, 2011 c, detector.error, 2010 c, detector.intensity, 2011 c, detector.error, 2012 2012 c, detector.events); 2013 2013 printf(" \"%s\"\n", strlen(detector.filename) ? detector.filename : detector.component); 2014 2015 if (hasnan) 2014 2015 if (hasnan) 2016 2016 printf("WARNING: Nan detected in component %s\n", detector.component); 2017 if (hasinf) 2017 if (hasinf) 2018 2018 printf("WARNING: Inf detected in component %s\n", detector.component); 2019 2019 2020 2020 /* add warning in case of low statistics or large number of bins in text format mode */ 2021 if (detector.error > detector.intensity/4) 2021 if (detector.error > detector.intensity/4) 2022 2022 printf("WARNING: file '%s': Low Statistics\n", detector.filename); 2023 2023 else if (strlen(detector.filename)) { 2024 if (m*n*p > 1000 && Nsum < m*n*p && Nsum) 2024 if (m*n*p > 1000 && Nsum < m*n*p && Nsum) 2025 2025 printf( 2026 2026 "WARNING: file '%s': Low Statistics (%g events in %ldx%ldx%ld bins).\n", … … 2034 2034 detector.filename, format.Name, m,n,p); 2035 2035 } 2036 2036 2037 2037 if (mcDetectorCustomHeader && strlen(mcDetectorCustomHeader)) { 2038 2038 if (strstr(detector.format.Name, "Octave") || strstr(detector.format.Name, "Matlab")) … … 2056 2056 #ifdef USE_MPI 2057 2057 /* only for Master */ 2058 if(mpi_node_rank != mpi_node_root) return(NULL); 2058 if(mpi_node_rank != mpi_node_root) return(NULL); 2059 2059 #endif 2060 2060 2061 2061 if (detector.m) { 2062 2062 /* add detector entry in the mcDetectorArray */ 2063 if (!mcDetectorArray || 2063 if (!mcDetectorArray || 2064 2064 (mcDetectorArray && mcDetectorArray_size <= mcDetectorArray_index)) { 2065 2065 mcDetectorArray_size+=CHAR_BUF_LENGTH; … … 2073 2073 2074 2074 return(mcDetectorArray); 2075 2075 2076 2076 } /* mcdetector_register */ 2077 2077 … … 2083 2083 MCDETECTOR mcdetector_import_sim(void) { 2084 2084 Coords zero={0.0,0.0,0.0}; 2085 MCDETECTOR detector=mcdetector_import(mcformat, "mcstas", NULL, 2085 MCDETECTOR detector=mcdetector_import(mcformat, "mcstas", NULL, 2086 2086 0,0,0, /* mnp */ 2087 2087 NULL, NULL, NULL, /* labels */ … … 2104 2104 static int mcsiminfo_init(FILE *f) 2105 2105 { 2106 2106 2107 2107 #ifdef USE_MPI 2108 2108 /* only for Master */ 2109 if(mpi_node_rank != mpi_node_root) return(-1); 2109 if(mpi_node_rank != mpi_node_root) return(-1); 2110 2110 #endif 2111 2111 if (mcdisable_output_files) return(-2); … … 2114 2114 /* clear list of opened files to start new save session */ 2115 2115 if (mcopenedfiles && strlen(mcopenedfiles) > 0) strcpy(mcopenedfiles, ""); 2116 2116 2117 2117 /* open sim file ========================================================== */ 2118 2118 2119 2119 #ifdef USE_NEXUS 2120 2120 /* NeXus sim info is the NeXus root file. */ … … 2135 2135 else mcsiminfo_file = f; 2136 2136 } 2137 2137 2138 2138 if(!mcsiminfo_file) 2139 2139 return(-fprintf(stderr, 2140 2140 "Warning: could not open simulation description file '%s' (mcsiminfo_init)\n", 2141 2141 mcsiminfo_name)); 2142 2142 2143 2143 /* initialize sim file information, sets detector.file_handle=mcsiminfo_file */ 2144 2144 MCDETECTOR mcsiminfo = mcdetector_import_sim(); 2145 2145 2146 2146 /* flag true for McStas or NX data format */ 2147 int ismcstas_nx= (strstr(mcformat.Name, "McStas") || strstr(mcformat.Name, "NeXus")); 2148 2147 int ismcstas_nx= (strstr(mcformat.Name, "McStas") || strstr(mcformat.Name, "NeXus")); 2148 2149 2149 /* start to write meta data =============================================== */ 2150 2150 … … 2168 2168 mcsiminfo = mcfile_section(mcsiminfo, "begin", mcsiminfo.simulation, mcinstrument_name, "instrument", 1); 2169 2169 mcinfo_instrument(mcsiminfo, mcinstrument_name); 2170 2170 2171 2171 #ifdef USE_NEXUS 2172 2172 if (strstr(mcformat.Name, "NeXus")) { … … 2184 2184 mcsiminfo = mcfile_section(mcsiminfo, "begin", mcsiminfo.simulation, mcsiminfo_name, "simulation", 2); 2185 2185 mcsiminfo = mcinfo_simulation(mcsiminfo, mcsiminfo_name); 2186 2186 2187 2187 #ifdef USE_NEXUS 2188 2188 /* close information SDS opened with mcfile_section(siminfo,"simulation") */ … … 2212 2212 2213 2213 mcdetector_write_content(mcDetectorArray, mcDetectorArray_index); 2214 2214 2215 2215 /* initialize sim file information, sets detector.file_handle=mcsiminfo_file */ 2216 2216 MCDETECTOR mcsiminfo = mcdetector_import_sim(); 2217 2217 2218 2218 /* close those sections which were opened in mcsiminfo_init =============== */ 2219 if (!ismcstas_nx) { 2219 if (!ismcstas_nx) { 2220 2220 mcfile_section(mcsiminfo, "end", mcsiminfo.simulation, mcsiminfo_name, "simulation", 2); 2221 2221 mcfile_section(mcsiminfo, "end", mcsiminfo.simulation, mcinstrument_name, "instrument", 1); … … 2234 2234 mcfile_section(mcsiminfo, "end", "mcstas", mcinstrument_name, "entry", 1); 2235 2235 } 2236 #endif 2237 2236 #endif 2237 2238 2238 /* close sim file ========================================================= */ 2239 2239 #ifdef USE_NEXUS … … 2262 2262 char valid_zlabel[VALID_NAME_LENGTH]; 2263 2263 char valid_parent[VALID_NAME_LENGTH]; 2264 2264 2265 2265 if (strstr(part,"data")) 2266 2266 { this_p1=detector.p1; Begin = detector.format.BeginData; End = detector.format.EndData; } … … 2269 2269 if (strstr(part,"ncount") || strstr(part,"events")) 2270 2270 { this_p1=detector.p0;Begin = detector.format.BeginNcount; End = detector.format.EndNcount; } 2271 2271 2272 2272 if (!this_p1 || mcdisable_output_files) return(-1); 2273 2273 if (!detector.file_handle && !strstr(detector.format.Name,"NeXus")) return(-1); 2274 2274 if (!detector.rank) return(-1); 2275 2275 2276 2276 2277 2277 mcvalid_name(valid_xlabel, detector.xlabel, VALID_NAME_LENGTH); 2278 2278 mcvalid_name(valid_ylabel, detector.ylabel, VALID_NAME_LENGTH); 2279 2279 mcvalid_name(valid_zlabel, detector.zlabel, VALID_NAME_LENGTH); 2280 2280 mcvalid_name(valid_parent, detector.filename, VALID_NAME_LENGTH); 2281 2281 2282 2282 /* output Begin =========================================================== */ 2283 if (!strstr(detector.format.Name,"NeXus") 2283 if (!strstr(detector.format.Name,"NeXus") 2284 2284 && (!strstr(detector.format.Name,"binary") || strstr(part,"empty array")) 2285 2285 && !strstr(detector.format.Name,"no header")) … … 2307 2307 detector.zmin, /* %21$g ZMIN */ 2308 2308 detector.zmax); /* %22$g ZMAX */ 2309 2309 2310 2310 /* output array */ 2311 2311 if (strstr(part,"empty array")) { 2312 2312 /* skip array output: set as empty */ 2313 2313 2314 2314 /* special case of IDL: can not have empty vectors. Init to 'external' */ 2315 2315 if (strstr(detector.format.Name, "IDL")) fprintf(detector.file_handle, "'external'"); 2316 2316 } else { 2317 #ifdef USE_NEXUS 2317 #ifdef USE_NEXUS 2318 2318 /* array NeXus ========================================================== */ 2319 2319 if (strstr(detector.format.Name,"NeXus")) { 2320 if(mcnxfile_data(mcnxHandle, detector, part, 2320 if(mcnxfile_data(mcnxHandle, detector, part, 2321 2321 valid_parent, valid_xlabel, valid_ylabel, valid_zlabel) == NX_ERROR) { 2322 2322 fprintf(stderr, "Error: writing NeXus data %s/%s (mcfile_data)\n", valid_parent, detector.filename); … … 2325 2325 return(1); 2326 2326 } /* end if NeXus */ 2327 #endif 2327 #endif 2328 2328 /* array non binary (text) ============================================== */ 2329 if (!strstr(detector.format.Name, "binary") 2330 && !strstr(detector.format.Name, "float") && !strstr(detector.format.Name, "double")) 2329 if (!strstr(detector.format.Name, "binary") 2330 && !strstr(detector.format.Name, "float") && !strstr(detector.format.Name, "double")) 2331 2331 { 2332 2332 char eol_char[3]; … … 2334 2334 int isPython = (strstr(detector.format.Name, "Python") != NULL); 2335 2335 int i,j; 2336 if (isIDL) strcpy(eol_char,"$\n"); 2337 else if (isPython) strcpy(eol_char,"\\\n"); 2336 if (isIDL) strcpy(eol_char,"$\n"); 2337 else if (isPython) strcpy(eol_char,"\\\n"); 2338 2338 else strcpy(eol_char,"\n"); 2339 2339 … … 2352 2352 } /* end 2 loops if not Binary */ 2353 2353 } /* end if !Binary */ 2354 2354 2355 2355 /* array binary double =================================================== */ 2356 if (strstr(detector.format.Name, "double")) 2356 if (strstr(detector.format.Name, "double")) 2357 2357 { 2358 2358 long count=0; 2359 2359 count = fwrite(this_p1, sizeof(double), detector.m*detector.n*detector.p, detector.file_handle); 2360 if (count != detector.m*detector.n*detector.p) 2360 if (count != detector.m*detector.n*detector.p) 2361 2361 fprintf(stderr, "Error: writing double binary file '%s' (%li instead of %li, mcfile_data)\n", detector.filename,count, detector.m*detector.n*detector.p); 2362 2362 } /* end if Binary double */ 2363 2363 2364 2364 /* array binary float =================================================== */ 2365 if (strstr(detector.format.Name, "binary") || strstr(detector.format.Name, "float")) 2365 if (strstr(detector.format.Name, "binary") || strstr(detector.format.Name, "float")) 2366 2366 { 2367 2367 float *s; … … 2370 2370 { 2371 2371 long i, count=0; 2372 for (i=0; i<detector.m*detector.n*detector.p; i++) { 2372 for (i=0; i<detector.m*detector.n*detector.p; i++) { 2373 2373 s[i] = (float)this_p1[i]; } 2374 2374 count = fwrite(s, sizeof(float), detector.m*detector.n*detector.p, detector.file_handle); 2375 if (count != detector.m*detector.n*detector.p) 2375 if (count != detector.m*detector.n*detector.p) 2376 2376 fprintf(stderr, "Error writing float binary file '%s' (%li instead of %li, mcfile_data)\n", 2377 2377 detector.filename,count, detector.m*detector.n*detector.p); 2378 2378 free(s); 2379 } else 2379 } else 2380 2380 fprintf(stderr, "Error: Out of memory for writing %li float binary file '%s' (mcfile_data)\n", 2381 2381 detector.m*detector.n*detector.p*sizeof(float), detector.filename); 2382 2382 } /* end if Binary float */ 2383 2383 } /* end if not empty array */ 2384 2384 2385 2385 /* output End ============================================================= */ 2386 2386 if (!strstr(detector.format.Name,"NeXus") … … 2421 2421 /* MPI: only write sim by Master ========================================== */ 2422 2422 #ifdef USE_MPI 2423 if(mpi_node_rank != mpi_node_root) return(detector); 2423 if(mpi_node_rank != mpi_node_root) return(detector); 2424 2424 #endif 2425 2425 /* skip invalid detectors */ 2426 2426 if (!detector.m || mcdisable_output_files) return(detector); 2427 2427 2428 /* sim file has been initialized when starting simulation and when calling 2428 /* sim file has been initialized when starting simulation and when calling 2429 2429 * mcsave ; this defines mcsiminfo_file as the SIM file handle 2430 * and calls: 2430 * and calls: 2431 2431 * mcinfo_header 2432 2432 * mcfile_section begin instrument … … 2441 2441 * The sim file (and mcnxHandle) is closed when ending mcsave 2442 2442 */ 2443 2443 2444 2444 MCDETECTOR simfile = mcdetector_import_sim(); /* store reference structure to SIM file */ 2445 2445 2446 2446 /* add component and data section to SIM file */ 2447 2447 if (!strstr(detector.format.Name,"NeXus")) 2448 2448 simfile = mcfile_section(simfile, "begin", detector.simulation, detector.component, "component", 3); 2449 2449 simfile = mcfile_section(simfile, "begin", detector.component, detector.filename, "data", 4); 2450 2450 2451 2451 /* handle indentation for simfile */ 2452 2452 char prefix[CHAR_BUF_LENGTH]; 2453 2453 strncpy(prefix, detector.prefix, CHAR_BUF_LENGTH); 2454 2454 strncpy(detector.prefix, simfile.prefix, CHAR_BUF_LENGTH); 2455 2455 2456 2456 /* WRITE detector information to sim file ================================= */ 2457 2457 mcinfo_data(detector, NULL); … … 2462 2462 fprintf(stderr, "Warning: NeXus: could not close data set %s/information\n", 2463 2463 detector.filename); 2464 #endif 2464 #endif 2465 2465 /* WRITE data link to SIM file */ 2466 2466 if (!strstr(detector.format.Name,"McStas") && !mcsingle_file) { … … 2472 2472 detector.file_handle = file; 2473 2473 } 2474 2474 2475 2475 /* close component and data sections in SIM file */ 2476 2476 simfile = mcfile_section(simfile, "end", detector.component, detector.filename, "data", 4); 2477 2477 if (!strstr(detector.format.Name,"NeXus")) 2478 2478 simfile = mcfile_section(simfile, "end", detector.simulation, detector.component, "component", 3); 2479 2479 2480 2480 strncpy(detector.prefix, prefix, CHAR_BUF_LENGTH); 2481 2481 2482 return(detector); 2482 return(detector); 2483 2483 } /* mcdetector_write_sim */ 2484 2484 … … 2486 2486 * mcdetector_write_data: write information to data file and catenate lists 2487 2487 * this is where we open/close data files 2488 * also free detector.p1=this_p1 field which may hold 2488 * also free detector.p1=this_p1 field which may hold 2489 2489 * 1D McStas [x I Ierr N] array which is set in mcdetector_import 2490 2490 *******************************************************************************/ … … 2492 2492 { 2493 2493 /* skip if 0D or no filename or no data (only stored in sim file) */ 2494 if (!detector.rank || !strlen(detector.filename) 2494 if (!detector.rank || !strlen(detector.filename) 2495 2495 || !detector.m) return(detector); 2496 2496 … … 2508 2508 } 2509 2509 #endif 2510 2510 2511 2511 /* OPEN data file (possibly appending if already opened) ================== */ 2512 2512 if (mcformat_data.Name && strlen(mcformat_data.Name) && !mcsingle_file) 2513 2513 detector.format = mcformat_data; 2514 2514 2515 2515 if (!strstr(detector.format.Name, "NeXus")) { 2516 2516 /* explicitely open data file if not NeXus format */ … … 2520 2520 strcpy(mode, 2521 2521 (strstr(detector.format.Name, "no header") 2522 || strstr(detector.format.Name, "append") || strstr(detector.format.Name, "catenate") 2522 || strstr(detector.format.Name, "append") || strstr(detector.format.Name, "catenate") 2523 2523 || strstr(mcopenedfiles, detector.filename) ? 2524 2524 "a" : "w")); 2525 2525 if (strstr(detector.format.Name, "binary")) strcat(mode, "b"); 2526 detector.file_handle = mcnew_file(!mcsingle_file ? 2527 detector.filename : mcsiminfo_name, 2526 detector.file_handle = mcnew_file(!mcsingle_file ? 2527 detector.filename : mcsiminfo_name, 2528 2528 detector.format.Extension, mode); 2529 2529 } else { … … 2532 2532 mcfile_section(detector, "begin", detector.component, detector.filename, "data", 4); 2533 2533 } 2534 2534 2535 2535 /* WRITE data header (except when in 'no header') */ 2536 2536 if (!strstr(detector.format.Name, "no header")) { … … 2550 2550 fprintf(stderr, "Warning: NeXus: could not close data set %s/information (footer)\n", 2551 2551 detector.filename); 2552 /* group remains opened for data to be written */ 2553 #endif 2554 2552 /* group remains opened for data to be written */ 2553 #endif 2554 2555 2555 /* case: list of events =================================================== */ 2556 2556 if (strstr(detector.format.Name," list ")) { 2557 2557 2558 2558 #ifdef USE_MPI 2559 2559 if (mpi_node_rank != mpi_node_root) { … … 2564 2564 if (mc_MPI_Send(mnp, 3, MPI_INT, mpi_node_root)!= MPI_SUCCESS) 2565 2565 fprintf(stderr, "Warning: proc %i to master: MPI_Send mnp list error (mcdetector_write_data)", mpi_node_rank); 2566 if (!detector.p1 2566 if (!detector.p1 2567 2567 || mc_MPI_Send(detector.p1, abs(mnp[0]*mnp[1]*mnp[2]), MPI_DOUBLE, mpi_node_root) != MPI_SUCCESS) 2568 2568 fprintf(stderr, "Warning: proc %i to master: MPI_Send p1 list error (mcdetector_write_data)", mpi_node_rank); … … 2573 2573 2574 2574 /* master node or non-MPI list: store data block */ 2575 int master_mnp[3]={detector.m,detector.n,detector.p}; 2576 2575 int master_mnp[3]={detector.m,detector.n,detector.p}; 2576 2577 2577 #ifdef USE_MPI 2578 2578 int node_i=0; … … 2591 2591 detector.p1 = this_p1; 2592 2592 detector.m = mnp[0]; detector.n = mnp[1]; detector.p = mnp[2]; 2593 } else 2593 } else 2594 2594 #endif 2595 2595 { /* MASTER/single node use its own detector structure */ … … 2597 2597 detector.m = master_mnp[0]; detector.n = master_mnp[1]; detector.p = master_mnp[2]; 2598 2598 } 2599 2599 2600 2600 /* WRITE list data (will be catenated in case of MPI as file is already opened) */ 2601 2601 mcfile_data(detector, "data"); 2602 2602 2603 2603 #ifdef USE_MPI 2604 2604 /* free temporary MPI block used for Recv from slaves */ 2605 if (this_p1 && node_i != mpi_node_root) 2605 if (this_p1 && node_i != mpi_node_root) 2606 2606 free(this_p1); 2607 2607 detector.p0 = detector.p0_orig; … … 2609 2609 detector.p2 = detector.p2_orig; 2610 2610 detector.m = master_mnp[0]; detector.n = master_mnp[1]; detector.p = master_mnp[2]; 2611 2611 2612 2612 } /* for node_i: end loop on nodes */ 2613 2613 #endif … … 2617 2617 { 2618 2618 /* case: normal detector ================================================== */ 2619 2619 2620 2620 /* WRITE data */ 2621 2621 mcfile_data(detector, "data"); 2622 2622 2623 2623 /* write errors (not for lists) */ 2624 2624 if (detector.p2) mcfile_data(detector, "errors"); 2625 2625 2626 2626 /* write events (not for lists) */ 2627 2627 if (detector.p0) mcfile_data(detector, "events"); 2628 2628 2629 2629 if (detector.rank == 1 && detector.p1 && strstr(detector.format.Name,"McStas")) { 2630 2630 free(detector.p1); /* 'this_p1' allocated in mcdetector_write_sim for 1D McStas data sets [x I E N] */ … … 2635 2635 } 2636 2636 } /* end normal detector case */ 2637 2637 2638 2638 /* WRITE data footer (except when 'no footer') */ 2639 2639 if (!strstr(detector.format.Name, "no footer") && !strstr(mcformat.Name, "NeXus")) { … … 2642 2642 mcinfo_header(detector, "footer"); 2643 2643 } 2644 2644 2645 2645 /* close data file and free memory */ 2646 2646 if (mcDetectorCustomHeader && strlen(mcDetectorCustomHeader)) { 2647 2647 free(mcDetectorCustomHeader); mcDetectorCustomHeader=NULL; } 2648 2648 2649 2649 if (!strstr(mcformat.Name, "NeXus") && detector.file_handle != mcsiminfo_file 2650 && !mcdisable_output_files && detector.file_handle) 2650 && !mcdisable_output_files && detector.file_handle) 2651 2651 fclose(detector.file_handle); 2652 2652 else if (strstr(mcformat.Name, "NeXus")) { … … 2655 2655 } 2656 2656 2657 return(detector); 2657 return(detector); 2658 2658 } /* mcdetector_write_data */ 2659 2659 … … 2666 2666 #ifdef USE_MPI 2667 2667 /* only for Master */ 2668 if(mpi_node_rank != mpi_node_root) return(-1); 2668 if(mpi_node_rank != mpi_node_root) return(-1); 2669 2669 #endif 2670 2670 if (mcdisable_output_files) return(-2); … … 2675 2675 double *this_p1 = (double *)calloc(DetectorArray_index*2, sizeof(double)); 2676 2676 int i; 2677 2677 2678 2678 if (this_p1 && DetectorArray) { 2679 2679 char *labels=NULL; … … 2689 2689 mcvalid_name(valid, DetectorArray[i].filename, CHAR_BUF_LENGTH); 2690 2690 sprintf(mem, "%s_I %s_Err ", valid, valid); 2691 if (!labels || 2691 if (!labels || 2692 2692 (labels && labels_size <= strlen(labels)+strlen(mem))) { 2693 2693 labels_size+=CHAR_BUF_LENGTH; … … 2696 2696 else 2697 2697 labels = realloc(labels, labels_size); 2698 } 2698 } 2699 2699 strcat(labels, " "); 2700 2700 strcat(labels, mem); 2701 2701 } /* for */ 2702 2702 2703 2703 struct mcformats_struct format=mcformat; 2704 2704 strcat(format.Name, " scan step"); 2705 2705 Coords zero={0.0,0.0,0.0}; 2706 2706 2707 2707 /* now create detector and write 'abstract' file */ 2708 2708 MCDETECTOR detector = mcdetector_import(format, … … 2713 2713 0, index-1, 0, 0, 0, 0, "content", /* use name from OpenOffice content.xml description file */ 2714 2714 NULL, this_p1, NULL, zero); 2715 2715 2716 2716 mcdetector_write_data(detector); 2717 2717 2718 2718 free(labels); labels=NULL; labels_size=0; 2719 2719 2720 2720 /* free DETECTOR array */ 2721 2721 free(this_p1); this_p1=NULL; … … 2739 2739 0, 0, 0, 0, 0, 0, "", 2740 2740 &p0, &p1, &p2, posa); /* write Detector: line */ 2741 2741 2742 2742 /* write detector to simulation file (incl custom header if any) */ 2743 detector = mcdetector_write_sim(detector); 2743 detector = mcdetector_write_sim(detector); 2744 2744 mcdetector_register(detector); 2745 2745 return(detector); … … 2750 2750 *******************************************************************************/ 2751 2751 MCDETECTOR mcdetector_out_1D(char *t, char *xl, char *yl, 2752 char *xvar, double x1, double x2, 2752 char *xvar, double x1, double x2, 2753 2753 int n, 2754 2754 double *p0, double *p1, double *p2, char *f, … … 2763 2763 x1, x2, 0, 0, 0, 0, f, 2764 2764 p0, p1, p2, posa); /* write Detector: line */ 2765 2765 2766 2766 /* write detector to simulation and data file (incl custom header if any) */ 2767 2767 detector = mcdetector_write_sim(detector); … … 2775 2775 *******************************************************************************/ 2776 2776 MCDETECTOR mcdetector_out_2D(char *t, char *xl, char *yl, 2777 double x1, double x2, double y1, double y2, 2778 int m, int n, 2777 double x1, double x2, double y1, double y2, 2778 int m, int n, 2779 2779 double *p0, double *p1, double *p2, char *f, 2780 2780 char *c, Coords posa) … … 2816 2816 MCDETECTOR mcdetector_out_3D(char *t, char *xl, char *yl, char *zl, 2817 2817 char *xvar, char *yvar, char *zvar, 2818 double x1, double x2, double y1, double y2, double z1, double z2, 2819 int m, int n, int p, 2820 double *p0, double *p1, double *p2, char *f, 2818 double x1, double x2, double y1, double y2, double z1, double z2, 2819 int m, int n, int p, 2820 double *p0, double *p1, double *p2, char *f, 2821 2821 char *c, Coords posa) 2822 2822 { … … 2829 2829 x1, x2, y1, y2, z1, z2, f, 2830 2830 p0, p1, p2, posa); /* write Detector: line */ 2831 2831 2832 2832 /* write detector to simulation and data file (incl custom header if any) */ 2833 2833 detector = mcdetector_write_sim(detector); … … 2838 2838 2839 2839 /******************************************************************************* 2840 * mcuse_format_header: Replaces aliases names in format fields (header part) 2840 * mcuse_format_header: Replaces aliases names in format fields (header part) 2841 2841 *******************************************************************************/ 2842 2842 char *mcuse_format_header(char *format_const) … … 2861 2861 2862 2862 /******************************************************************************* 2863 * mcuse_format_tag: Replaces aliases names in format fields (tag part) 2863 * mcuse_format_tag: Replaces aliases names in format fields (tag part) 2864 2864 *******************************************************************************/ 2865 2865 char *mcuse_format_tag(char *format_const) … … 2882 2882 2883 2883 /******************************************************************************* 2884 * mcuse_format_section: Replaces aliases names in format fields (section part) 2884 * mcuse_format_section: Replaces aliases names in format fields (section part) 2885 2885 *******************************************************************************/ 2886 2886 char *mcuse_format_section(char *format_const) … … 2904 2904 2905 2905 /******************************************************************************* 2906 * mcuse_format_data: Replaces aliases names in format fields (data part) 2906 * mcuse_format_data: Replaces aliases names in format fields (data part) 2907 2907 *******************************************************************************/ 2908 2908 char *mcuse_format_data(char *format_const) … … 3013 3013 3014 3014 /******************************************************************************* 3015 * mcclear_format: free format structure 3015 * mcclear_format: free format structure 3016 3016 *******************************************************************************/ 3017 3017 void mcclear_format(struct mcformats_struct usedformat) … … 3034 3034 3035 3035 /******************************************************************************* 3036 * mcuse_file: will save data/sim files 3036 * mcuse_file: will save data/sim files 3037 3037 *******************************************************************************/ 3038 3038 static void mcuse_file(char *file) … … 3049 3049 3050 3050 /******************************************************************************* 3051 * mcset_ncount: set total number of rays to generate 3051 * mcset_ncount: set total number of rays to generate 3052 3052 *******************************************************************************/ 3053 3053 void mcset_ncount(unsigned long long int count) … … 3072 3072 mcsetn_arg(char *arg) 3073 3073 { 3074 mcset_ncount((long long int) strtod(arg, NULL)); 3074 mcset_ncount((long long int) strtod(arg, NULL)); 3075 3075 } 3076 3076 … … 3386 3386 double cz = cos(phz); 3387 3387 double sz = sin(phz); 3388 3388 3389 3389 t[0][0] = cy*cz; 3390 3390 t[0][1] = sx*sy*cz + cx*sz; … … 3396 3396 t[2][1] = -sx*cy; 3397 3397 t[2][2] = cx*cy; 3398 } 3398 } 3399 3399 } 3400 3400 … … 3402 3402 * rot_test_identity: Test if rotation is identity 3403 3403 *******************************************************************************/ 3404 int 3404 int 3405 3405 rot_test_identity(Rotation t) 3406 3406 { … … 3465 3465 { 3466 3466 Coords b; 3467 if (rot_test_identity(t)) { 3467 if (rot_test_identity(t)) { 3468 3468 return a; 3469 3469 } else { … … 3526 3526 *z = b.z; 3527 3527 } 3528 3528 3529 3529 if (vx != NULL && vy != NULL && vz != NULL) mccoordschange_polarisation(t, vx, vy, vz); 3530 3530 3531 3531 if (sx != NULL && sy != NULL && sz != NULL) mccoordschange_polarisation(t, sx, sy, sz); 3532 3532 … … 3616 3616 { 3617 3617 int ret=0; 3618 3618 3619 3619 if (!t1) return 0; 3620 3620 *t1 = 0; … … 3657 3657 * randvec_target_circle: Choose random direction towards target at (x,y,z) 3658 3658 * with given radius. 3659 * If radius is zero, choose random direction in full 4PI, no target. 3659 * If radius is zero, choose random direction in full 4PI, no target. 3660 3660 ******************************************************************************/ 3661 3661 void … … 3722 3722 * (xi,yi,zi) with given ANGULAR dimension height x width. height=phi_x, 3723 3723 * width=phi_y (radians) 3724 * If height or width is zero, choose random direction in full 4PI, no target. 3724 * If height or width is zero, choose random direction in full 4PI, no target. 3725 3725 *******************************************************************************/ 3726 3726 void … … 3794 3794 * (See remarks posted to mcstas-users by George Apostolopoulus <gapost@ipta.demokritos.gr>) 3795 3795 * 3796 * If height or width is zero, choose random direction in full 4PI, no target. 3797 * 3796 * If height or width is zero, choose random direction in full 4PI, no target. 3797 * 3798 3798 * Traditionally, this routine had the name randvec_target_rect - this is now a 3799 3799 * a define (see mcstas-r.h) pointing here. If you use the old rouine, you are NOT 3800 * taking the local emmission coordinate into account. 3800 * taking the local emmission coordinate into account. 3801 3801 *******************************************************************************/ 3802 3802 3803 3803 void 3804 3804 randvec_target_rect_real(double *xo, double *yo, double *zo, double *solid_angle, 3805 double xi, double yi, double zi, 3806 double width, double height, Rotation A, 3805 double xi, double yi, double zi, 3806 double width, double height, Rotation A, 3807 3807 double lx, double ly, double lz, int order) 3808 3808 { … … 3873 3873 lz = *zo - lz; 3874 3874 dist_p = sqrt(lx*lx + ly*ly + lz*lz); 3875 3875 3876 3876 /* Adjust the 'solid angle' */ 3877 3877 /* 1/r^2 to the chosen point times cos(\theta) between the normal */ 3878 3878 /* vector of the target rectangle and direction vector of the chosen point. */ 3879 3879 cos_theta = (xi * lx + yi * ly + zi * lz) / (dist * dist_p); 3880 *solid_angle = width * height / (dist_p * dist_p); 3880 *solid_angle = width * height / (dist_p * dist_p); 3881 3881 int counter; 3882 3882 for (counter = 0; counter < order; counter++) { … … 4198 4198 } 4199 4199 4200 /** 4200 /** 4201 4201 * Return a random number between 1 and -1 4202 4202 */ … … 4229 4229 4230 4230 /******************************************************************************* 4231 * mchelp: displays instrument executable help with possible options 4231 * mchelp: displays instrument executable help with possible options 4232 4232 *******************************************************************************/ 4233 4233 static void … … 4292 4292 } /* mchelp */ 4293 4293 4294 4294 4295 /* mcshowhelp: show help and exit with 0 */ 4295 4296 static void … … 4297 4298 { 4298 4299 mchelp(pgmname); 4299 #ifdef USE_MPI4300 #undef exit4301 #endif4302 4300 exit(0); 4303 #ifdef USE_MPI4304 #define exit(code) MPI_Abort(MPI_COMM_WORLD, code)4305 #endif4306 4301 } 4307 4302 … … 4334 4329 /******************************************************************************* 4335 4330 * mcuse_dir: set data/sim storage directory and create it, 4336 * or exit with error if exists 4331 * or exit with error if exists 4337 4332 ******************************************************************************/ 4338 4333 static void … … 4345 4340 exit(1); 4346 4341 #else /* !MC_PORTABLE */ 4347 #ifdef USE_MPI 4342 #ifdef USE_MPI 4348 4343 if(mpi_node_rank == mpi_node_root) 4349 4344 { … … 4352 4347 #ifndef DANSE 4353 4348 fprintf(stderr, "Error: unable to create directory '%s' (mcuse_dir)\n", dir); 4354 fprintf(stderr, "(Maybe the directory already exists?)\n"); 4349 fprintf(stderr, "(Maybe the directory already exists?)\n"); 4355 4350 exit(1); 4356 4351 #endif … … 4364 4359 else 4365 4360 mcdirname = dir+strlen("file:/"); 4366 4361 4367 4362 /* remove trailing PATHSEP (if any) */ 4368 while (strlen(mcdirname) && mcdirname[strlen(mcdirname) - 1] == MC_PATHSEP_C) 4363 while (strlen(mcdirname) && mcdirname[strlen(mcdirname) - 1] == MC_PATHSEP_C) 4369 4364 mcdirname[strlen(mcdirname) - 1]='\0'; 4370 4365 #endif /* !MC_PORTABLE */ … … 4372 4367 4373 4368 /******************************************************************************* 4374 * mcinfo: display instrument simulation info to stdout and exit 4369 * mcinfo: display instrument simulation info to stdout and exit 4375 4370 *******************************************************************************/ 4376 4371 static void … … 4391 4386 4392 4387 /******************************************************************************* 4393 * mcreadparams: request parameters from the prompt (or use default) 4388 * mcreadparams: request parameters from the prompt (or use default) 4394 4389 *******************************************************************************/ 4395 4390 void … … 4474 4469 4475 4470 /******************************************************************************* 4476 * mcparseoptions: parse command line arguments (options, parameters) 4471 * mcparseoptions: parse command line arguments (options, parameters) 4477 4472 *******************************************************************************/ 4478 4473 void … … 4584 4579 } 4585 4580 else if(!strcmp("--no-output-files", argv[i])) 4586 mcdisable_output_files = 1; 4581 mcdisable_output_files = 1; 4587 4582 else if(argv[i][0] != '-' && (p = strchr(argv[i], '=')) != NULL) 4588 4583 { … … 4643 4638 4644 4639 #ifndef NOSIGNALS 4645 mcstatic char mcsig_message[256]; 4646 4647 4648 /******************************************************************************* 4649 * sighandler: signal handler that makes simulation stop, and save results 4640 mcstatic char mcsig_message[256]; 4641 4642 4643 /******************************************************************************* 4644 * sighandler: signal handler that makes simulation stop, and save results 4650 4645 *******************************************************************************/ 4651 4646 void sighandler(int sig) … … 4727 4722 else 4728 4723 { 4729 printf("%.2f %% (%10.1f/%10.1f)\n", 100.0*mcget_run_num()/mcget_ncount(), 1.0*mcget_run_num(), 1.0*mcget_ncount()); 4724 printf("%.2f %% (%10.1f/%10.1f)\n", 100.0*mcget_run_num()/mcget_ncount(), 1.0*mcget_run_num(), 1.0*mcget_ncount()); 4730 4725 } 4731 4726 t0 = (time_t)mcstartdate; … … 4771 4766 4772 4767 /******************************************************************************* 4773 * mccode_main: McCode main() function. 4768 * mccode_main: McCode main() function. 4774 4769 *******************************************************************************/ 4775 4770 int mccode_main(int argc, char *argv[])
