Code Monkey home page Code Monkey logo

pvadriver's Introduction

pvadriver's People

Contributors

aawdls avatar adambark avatar ajgdls avatar bhill-slac avatar brunoseivam avatar coretl avatar edwarrick avatar jlmuir avatar keenanlang avatar markrivers avatar mdmoo1978 avatar mp49 avatar prjemian avatar roehrig avatar ronaldomercado avatar stuwilkins avatar timmmooney avatar ulrikpedersen avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pvadriver's Issues

Poor performance with default request type queue size

Hi,

I've been playing around with pvaDriver today, transporting 0.5MB images between two areaDetector IOCs with and without LZ4 compression.

I saw poor performance with the pvaDriver with even a low frame rate of 100Hz (only 50MB/s), in that I was dropping arrays every few seconds.

Then I made this change in pvaDriver:

diff --git a/pvaDriverApp/src/pvaDriver.cpp b/pvaDriverApp/src/pvaDriver.cpp
index 02b5d4a..278c21f 100644
--- a/pvaDriverApp/src/pvaDriver.cpp
+++ b/pvaDriverApp/src/pvaDriver.cpp
@@ -23,8 +23,8 @@
#include <epicsExport.h>
#include "pvaDriver.h"

-//#define DEFAULT_REQUEST "record[queueSize=100]field()"
-#define DEFAULT_REQUEST "field()"
+#define DEFAULT_REQUEST "record[queueSize=100]field()"
+//#define DEFAULT_REQUEST "field()"

And that worked wonders. I was able to reliably run at 100Hz, 800Hz and even 1500Hz without dropping frames.

It seems like that driver was used with queueSize=100 at some point but that it was commented out.

I think this parameter could be made configurable as an argument to pvaDriverConfig(). Does that sound reasonable? If so, I can make a pull request and test it.

Matt

connectPv exception on IOC start up

I am currently trying to update DLS to ADCore 2-6, plus the other dependencies that come with that.

I have two IOCs, one with a SimDetector and pvaPlugin, the other with a pvaDriver, PosPlugin and HDF5Plugin. It works OK with our most recent internal ADCore 2-4 release. (We imported pvaDriver at this commit dls-controls/ADCore@834944c). The PvName is set, reports up and I am able to get frames and capture an image.

When testing the pvaDriver in its new repository I got the following error:

2017/04/05 16:09:17.358 pvaDriver::connectPv exception initializing monitor: 0 or empty channel name
2017/04/05 16:09:17.359 MAP-DI-TEST-01:CAM:PvName devAsynOctet::writeIt failed pvaDriver:writeOctet: status=3, function=87, value=

and on start up, the PvName is empty and reports as Down and I can't get any frames through. Here is the console output where I have added some debug statements; PvName and 4 numbers throughout the connectPv function and the value asked to set in the writeOctet function.

 > bin/linux-x86_64/sttestPVDriver.sh 
# This file was automatically generated on Tue 04 Apr 2017 16:50:49 BST from
# source: /dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/etc/makeIocs/testPVDriver.xml
# 
# *** Please do not edit this file: edit the source file instead. ***
# 
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
epicsEnvSet "EPICS_TS_MIN_WEST", '0'
# Loading libraries
# -----------------
# Device initialisation
# ---------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadDatabase "dbd/testPVDriver.dbd"
testPVDriver_registerRecordDeviceDriver(pdbbase)
# pvaDriverConfig(portName, pvName, maxBuffers, maxMemory, priority, stackSize)
pvaDriverConfig("SIM.CAM", TESTPV1, 50, 0, 0, 0)
PV Name: TESTPV1
1
2
3
4
# NDPosPluginConfigure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory, priority, stackSize)
NDPosPluginConfigure("SIM.POS", 2, 0, "SIM.CAM", 0, 50, 0, 0, 0)
# NDFileHDF5Configure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory)
NDFileHDF5Configure("SIM.HDF", 1000, 0, "SIM.POS", 0, 50, 0)
# Final ioc initialisation
# ------------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadRecords 'db/testPVDriver_expanded.db'
iocInit
Starting iocInit
############################################################################
## EPICS R3.14.12.3 $Date: Mon 2012-12-17 14:11:47 -0600$
## EPICS Base built Mar 18 2015
############################################################################
Writing Octet ''
Writing Octet ''
PV Name: 
1
2
2017/04/05 16:37:48.285 pvaDriver::connectPv exception initializing monitor: 0 or empty channel name
2017/04/05 16:37:48.285 MAP-DI-TEST-01:CAM:PvName devAsynOctet::writeIt failed pvaDriver:writeOctet: status=3, function=87, value=
cas warning: Configured TCP port was unavailable.
cas warning: Using dynamically assigned TCP port 38347,
cas warning: but now two or more servers share the same UDP port.
cas warning: Depending on your IP kernel this server may not be
cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
iocRun: All initialization complete
epics>

I tried playing with the pvaDriver source to find the problem and it seems like, between pvaDriverConfig() and connectPv() being called a second time, something is calling writeOctet to set PvName to a blank string. I added a check to refuse to set PvName if the value is blank and that seems to fix the issue. The PvName is blank, but reports up and I can get frames and capture an image.

I tried checking out the ADCore 2-6 and pvaDriver 1-1 releases, alongside the DLS configure/ folder and I get the same issue.

 > bin/linux-x86_64/sttestPVDriver.sh 
# This file was automatically generated on Tue 04 Apr 2017 16:50:49 BST from
# source: /dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/etc/makeIocs/testPVDriver.xml
# 
# *** Please do not edit this file: edit the source file instead. ***
# 
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
epicsEnvSet "EPICS_TS_MIN_WEST", '0'
# Loading libraries
# -----------------
# Device initialisation
# ---------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadDatabase "dbd/testPVDriver.dbd"
testPVDriver_registerRecordDeviceDriver(pdbbase)
# pvaDriverConfig(portName, pvName, maxBuffers, maxMemory, priority, stackSize)
pvaDriverConfig("SIM.CAM", TESTPV1, 50, 0, 0, 0)
# NDPosPluginConfigure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory, priority, stackSize)
NDPosPluginConfigure("SIM.POS", 2, 0, "SIM.CAM", 0, 50, 0, 0, 0)
# NDFileHDF5Configure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory)
NDFileHDF5Configure("SIM.HDF", 1000, 0, "SIM.POS", 0, 50, 0)
# Final ioc initialisation
# ------------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadRecords 'db/testPVDriver_expanded.db'
iocInit
Starting iocInit
############################################################################
## EPICS R3.14.12.3 $Date: Mon 2012-12-17 14:11:47 -0600$
## EPICS Base built Mar 18 2015
############################################################################
2017/04/05 16:40:03.678 pvaDriver::connectPv exception initializing monitor: 0 or empty channel name
2017/04/05 16:40:03.678 MAP-DI-TEST-01:CAM:PvName devAsynOctet::writeIt failed pvaDriver:writeOctet: status=3, function=87, value=
cas warning: Configured TCP port was unavailable.
cas warning: Using dynamically assigned TCP port 45807,
cas warning: but now two or more servers share the same UDP port.
cas warning: Depending on your IP kernel this server may not be
cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
iocRun: All initialization complete
epics>

and with my check

 > bin/linux-x86_64/sttestPVDriver.sh 
# This file was automatically generated on Tue 04 Apr 2017 16:50:49 BST from
# source: /dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/etc/makeIocs/testPVDriver.xml
# 
# *** Please do not edit this file: edit the source file instead. ***
# 
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
epicsEnvSet "EPICS_TS_MIN_WEST", '0'
# Loading libraries
# -----------------
# Device initialisation
# ---------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadDatabase "dbd/testPVDriver.dbd"
testPVDriver_registerRecordDeviceDriver(pdbbase)
# pvaDriverConfig(portName, pvName, maxBuffers, maxMemory, priority, stackSize)
pvaDriverConfig("SIM.CAM", TESTPV1, 50, 0, 0, 0)
PV Name: TESTPV1
1
2
3
4
# NDPosPluginConfigure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory, priority, stackSize)
NDPosPluginConfigure("SIM.POS", 2, 0, "SIM.CAM", 0, 50, 0, 0, 0)
# NDFileHDF5Configure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory)
NDFileHDF5Configure("SIM.HDF", 1000, 0, "SIM.POS", 0, 50, 0)
# Final ioc initialisation
# ------------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadRecords 'db/testPVDriver_expanded.db'
iocInit
Starting iocInit
############################################################################
## EPICS R3.14.12.3 $Date: Mon 2012-12-17 14:11:47 -0600$
## EPICS Base built Mar 18 2015
############################################################################
Writing Octet ''
Writing Octet ''
Not changing PV Name from 'TESTPV1' to ''
PV Name: TESTPV1
1
2
3
4
cas warning: Configured TCP port was unavailable.
cas warning: Using dynamically assigned TCP port 46015,
cas warning: but now two or more servers share the same UDP port.
cas warning: Depending on your IP kernel this server may not be
cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
iocRun: All initialization complete
epics> 

Any idea what the problem is?

Looking for help with PVADriver IOC

AFter starting PVA IOC, the PV Connection status is always Down.
MEDM screen attached below, followed by IOC startup log.

image

PVADriver startup log:
================================
../../bin/linux-x86_64/pvaDriverApp st.cmd
< envPaths
epicsEnvSet("IOC","iocPvaDriver")
epicsEnvSet("TOP","/opt/epics/modules/synApps_6_1_epics7/support/areaDetector-R3-7/pvaDriver/iocs/pvaDriverIOC")
epicsEnvSet("PVADRIVER","/opt/epics/modules/synApps_6_1_epics7/support/areaDetector-R3-7/pvaDriver/iocs/pvaDriverIOC/../..")
epicsEnvSet("SUPPORT","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support")
epicsEnvSet("ASYN","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/asyn-R4-38")
epicsEnvSet("AREA_DETECTOR","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7")
epicsEnvSet("ADSUPPORT","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADSupport")
epicsEnvSet("ADCORE","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore")
epicsEnvSet("AUTOSAVE","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/autosave-R5-10")
epicsEnvSet("BUSY","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/busy-R1-7-2")
epicsEnvSet("CALC","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/calc-R3-7-4")
epicsEnvSet("SNCSEQ","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/seq-2-2-7")
epicsEnvSet("SSCAN","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/sscan-R2-11-3")
epicsEnvSet("DEVIOCSTATS","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/iocStats-3-1-16")
epicsEnvSet("STD","/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/std-R3-6-1")
epicsEnvSet("EPICS_BASE","/opt/epics/base-7.0.4")
< st_base.cmd
# Must have loaded envPaths via st.cmd*
errlogInit(20000)
dbLoadDatabase("/opt/epics/modules/synApps_6_1_epics7/support/areaDetector-R3-7/pvaDriver/iocs/pvaDriverIOC/dbd/pvaDriverApp.dbd")
pvaDriverApp_registerRecordDeviceDriver(pdbbase)
# Prefix for all records
epicsEnvSet("PREFIX", "13PVA1:")
# The port name for the detector
epicsEnvSet("PORT",   "PVA")
# The queue size for all plugins
epicsEnvSet("QSIZE",  "20")
# The maximim image width; used to set the maximum size for this driver and for row profiles in the NDPluginStats plugin
epicsEnvSet("XSIZE",  "1024")
# The maximim image height; used to set the maximum size for this driver and for column profiles in the NDPluginStats plugin
epicsEnvSet("YSIZE",  "1024")
# The maximum number of time series points in the NDPluginStats plugin
epicsEnvSet("NCHANS", "2048")
# The maximum number of frames buffered in the NDPluginCircularBuff plugin
epicsEnvSet("CBUFFS", "500")
# The search path for database files
epicsEnvSet("EPICS_DB_INCLUDE_PATH", "/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/db")
# The name of the EPICS V4 PV
epicsEnvSet("PVNAME", "13SIM1:Pva1:Image")
asynSetMinTimerPeriod(0.001)
asynSetMinTimerPeriod is not currently supported on this OS
# The EPICS environment variable EPICS_CA_MAX_ARRAY_BYTES needs to be set to a value at least as large
# as the largest image that the standard arrays plugin will send.
# That vlaue is $(XSIZE) * $(YSIZE) * sizeof(FTVL data type) for the FTVL used when loading the NDStdArrays.template file.
# The variable can be set in the environment before running the IOC or it can be set here.
# It is often convenient to set it in the environment outside the IOC to the largest array any client 
# or server will need.  For example 10000000 (ten million) bytes may be enough.
# If it is set here then remember to also set it outside the IOC for any CA clients that need to access the waveform record.  
# Do not set EPICS_CA_MAX_ARRAY_BYTES to a value much larger than that required, because EPICS Channel Access actually
# allocates arrays of this size every time it needs a buffer larger than 16K.
# Uncomment the following line to set it in the IOC.
#epicsEnvSet("EPICS_CA_MAX_ARRAY_BYTES", "10000000")
# Create a pvaDriver
# pvaDriverConfig(portName, pvName, maxBuffers, maxMemory, priority, stackSize)
pvaDriverConfig("PVA", "13SIM1:Pva1:Image", 0, 0, 0, 0)
#asynSetTraceMask $(PORT) 0 0xFF
#asynSetTraceInfoMask $(PORT) 0 0x7
dbLoadRecords("/opt/epics/modules/synApps_6_1_epics7/support/areaDetector-R3-7/pvaDriver/iocs/pvaDriverIOC/../../db/pvaDriver.template","P=13PVA1:,R=cam1:,PORT=PVA,ADDR=0,TIMEOUT=1")
# Create a standard arrays plugin, set it to get data from the pvaDriver.
NDStdArraysConfigure("Image1", 3, 0, "PVA", 0)
# This creates a waveform large enough for 2000x2000x3 (e.g. RGB color) arrays.
# This waveform only allows transporting 8-bit images
#dbLoadRecords("NDStdArrays.template", "P=$(PREFIX),R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),TYPE=Int8,FTVL=UCHAR,NELEMENTS=12000000")
# This waveform only allows transporting 16-bit images
#dbLoadRecords("NDStdArrays.template", "P=$(PREFIX),R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),TYPE=Int16,FTVL=SHORT,NELEMENTS=12000000")
# This waveform allows transporting 32-bit images
#dbLoadRecords("NDStdArrays.template", "P=$(PREFIX),R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),TYPE=Int32,FTVL=LONG,NELEMENTS=12000000")
# This waveform allows transporting 64-bit float images
dbLoadRecords("NDStdArrays.template", "P=13PVA1:,R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA,TYPE=Float64,FTVL=DOUBLE,NELEMENTS=12000000")
# Load all other plugins using commonPlugins.cmd
< /opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/iocBoot/commonPlugins.cmd
# This is an example file for creating plugins
# It uses the following environment variable macros
# Many of the parameters defined in this file are also in commonPlugins_settings.req so if autosave is being
# use the autosave value will replace the value passed to this file.

# $(PREFIX)      Prefix for all records
# $(PORT)        The port name for the detector.  In autosave.
# $(QSIZE)       The queue size for all plugins.  In autosave.
# $(XSIZE)       The maximum image width; used to set the maximum size for row profiles in the NDPluginStats plugin and 1-D FFT
#                   profiles in NDPluginFFT.
# $(YSIZE)       The maximum image height; used to set the maximum size for column profiles in the NDPluginStats plugin
# $(NCHANS)      The maximum number of time series points in the NDPluginStats, NDPluginROIStats, and NDPluginAttribute plugins
# $(CBUFFS)      The maximum number of frames buffered in the NDPluginCircularBuff plugin
# $(MAX_THREADS) The maximum number of threads for plugins which can run in multiple threads. Defaults to 5.

# Create a netCDF file saving plugin
NDFileNetCDFConfigure("FileNetCDF1", 20, 0, "PVA", 0)
dbLoadRecords("NDFileNetCDF.template","P=13PVA1:,R=netCDF1:,PORT=FileNetCDF1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create a TIFF file saving plugin
NDFileTIFFConfigure("FileTIFF1", 20, 0, "PVA", 0)
dbLoadRecords("NDFileTIFF.template",  "P=13PVA1:,R=TIFF1:,PORT=FileTIFF1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create a JPEG file saving plugin
NDFileJPEGConfigure("FileJPEG1", 20, 0, "PVA", 0)
dbLoadRecords("NDFileJPEG.template",  "P=13PVA1:,R=JPEG1:,PORT=FileJPEG1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create a NeXus file saving plugin
NDFileNexusConfigure("FileNexus1", 20, 0, "PVA", 0)
dbLoadRecords("NDFileNexus.template", "P=13PVA1:,R=Nexus1:,PORT=FileNexus1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create an HDF5 file saving plugin
NDFileHDF5Configure("FileHDF1", 20, 0, "PVA", 0)
dbLoadRecords("NDFileHDF5.template",  "P=13PVA1:,R=HDF1:,PORT=FileHDF1,ADDR=0,TIMEOUT=1,XMLSIZE=2048,NDARRAY_PORT=PVA")

# Create a Magick file saving plugin
#NDFileMagickConfigure("FileMagick1", $(QSIZE), 0, "$(PORT)", 0)
#dbLoadRecords("NDFileMagick.template","P=$(PREFIX),R=Magick1:,PORT=FileMagick1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")

# Create 4 ROI plugins
NDROIConfigure("ROI1", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDROI.template",       "P=13PVA1:,R=ROI1:,  PORT=ROI1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")
NDROIConfigure("ROI2", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDROI.template",       "P=13PVA1:,R=ROI2:,  PORT=ROI2,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")
NDROIConfigure("ROI3", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDROI.template",       "P=13PVA1:,R=ROI3:,  PORT=ROI3,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")
NDROIConfigure("ROI4", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDROI.template",       "P=13PVA1:,R=ROI4:,  PORT=ROI4,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create 8 ROIStat plugins
NDROIStatConfigure("ROISTAT1", 20, 0, "PVA", 0, 8, 0, 0, 0, 0, 5)
dbLoadRecords("NDROIStat.template",   "P=13PVA1:,R=ROIStat1:  ,PORT=ROISTAT1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=13PVA1:,R=ROIStat1:1:,PORT=ROISTAT1,ADDR=0,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=13PVA1:,R=ROIStat1:2:,PORT=ROISTAT1,ADDR=1,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=13PVA1:,R=ROIStat1:3:,PORT=ROISTAT1,ADDR=2,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=13PVA1:,R=ROIStat1:4:,PORT=ROISTAT1,ADDR=3,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=13PVA1:,R=ROIStat1:5:,PORT=ROISTAT1,ADDR=4,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=13PVA1:,R=ROIStat1:6:,PORT=ROISTAT1,ADDR=5,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=13PVA1:,R=ROIStat1:7:,PORT=ROISTAT1,ADDR=6,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=13PVA1:,R=ROIStat1:8:,PORT=ROISTAT1,ADDR=7,TIMEOUT=1,NCHANS=2048")

# Create a processing plugin
NDProcessConfigure("PROC1", 20, 0, "PVA", 0, 0, 0)
dbLoadRecords("NDProcess.template",   "P=13PVA1:,R=Proc1:,  PORT=PROC1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")
# Create a TIFF file plugin to read dark and flatfield images into the processing plugin
NDFileTIFFConfigure("PROC1TIFF", 20, 0, "PVA", 0)
dbLoadRecords("NDFileTIFF.template",  "P=13PVA1:,R=Proc1:TIFF:,PORT=PROC1TIFF,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create a scatter plugin
NDScatterConfigure("SCATTER1", 20, 0, "PVA", 0, 0, 0)
dbLoadRecords("NDScatter.template",   "P=13PVA1:,R=Scatter1:,  PORT=SCATTER1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create a gather plugin with 8 ports
NDGatherConfigure("GATHER1", 20, 0, 8, 0, 0)
dbLoadRecords("NDGather.template",   "P=13PVA1:,R=Gather1:, PORT=GATHER1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDGatherN.template",   "P=13PVA1:,R=Gather1:, N=1, PORT=GATHER1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDGatherN.template",   "P=13PVA1:,R=Gather1:, N=2, PORT=GATHER1,ADDR=1,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDGatherN.template",   "P=13PVA1:,R=Gather1:, N=3, PORT=GATHER1,ADDR=2,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDGatherN.template",   "P=13PVA1:,R=Gather1:, N=4, PORT=GATHER1,ADDR=3,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDGatherN.template",   "P=13PVA1:,R=Gather1:, N=5, PORT=GATHER1,ADDR=4,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDGatherN.template",   "P=13PVA1:,R=Gather1:, N=6, PORT=GATHER1,ADDR=5,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDGatherN.template",   "P=13PVA1:,R=Gather1:, N=7, PORT=GATHER1,ADDR=6,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDGatherN.template",   "P=13PVA1:,R=Gather1:, N=8, PORT=GATHER1,ADDR=7,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create 5 statistics plugins
NDStatsConfigure("STATS1", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=13PVA1:,R=Stats1:,  PORT=STATS1,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=PVA")
NDTimeSeriesConfigure("STATS1_TS", 20, 0, "STATS1", 1, 23)
dbLoadRecords("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/db/NDTimeSeries.template",  "P=13PVA1:,R=Stats1:TS:, PORT=STATS1_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS1,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")

NDStatsConfigure("STATS2", 20, 0, "ROI1",    0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=13PVA1:,R=Stats2:,  PORT=STATS2,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=PVA")
NDTimeSeriesConfigure("STATS2_TS", 20, 0, "STATS2", 1, 23)
dbLoadRecords("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/db/NDTimeSeries.template",  "P=13PVA1:,R=Stats2:TS:, PORT=STATS2_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS2,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")

NDStatsConfigure("STATS3", 20, 0, "ROI2",    0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=13PVA1:,R=Stats3:,  PORT=STATS3,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=PVA")
NDTimeSeriesConfigure("STATS3_TS", 20, 0, "STATS3", 1, 23)
dbLoadRecords("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/db/NDTimeSeries.template",  "P=13PVA1:,R=Stats3:TS:, PORT=STATS3_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS3,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")

NDStatsConfigure("STATS4", 20, 0, "ROI3",    0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=13PVA1:,R=Stats4:,  PORT=STATS4,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=PVA")
NDTimeSeriesConfigure("STATS4_TS", 20, 0, "STATS4", 1, 23)
dbLoadRecords("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/db/NDTimeSeries.template",  "P=13PVA1:,R=Stats4:TS:, PORT=STATS4_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS4,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")

NDStatsConfigure("STATS5", 20, 0, "ROI4",    0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=13PVA1:,R=Stats5:,  PORT=STATS5,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=PVA")
NDTimeSeriesConfigure("STATS5_TS", 20, 0, "STATS5", 1, 23)
dbLoadRecords("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/db/NDTimeSeries.template",  "P=13PVA1:,R=Stats5:TS:, PORT=STATS5_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS5,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")

# Create a transform plugin
NDTransformConfigure("TRANS1", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDTransform.template", "P=13PVA1:,R=Trans1:,  PORT=TRANS1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create an overlay plugin with 8 overlays
NDOverlayConfigure("OVER1", 20, 0, "PVA", 0, 8, 0, 0, 0, 0, 5)
dbLoadRecords("NDOverlay.template", "P=13PVA1:,R=Over1:, PORT=OVER1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")
dbLoadRecords("NDOverlayN.template","P=13PVA1:,R=Over1:1:,NAME=ROI1,   SHAPE=1,O=Over1:,XPOS=13PVA1:ROI1:MinX_RBV,YPOS=13PVA1:ROI1:MinY_RBV,XSIZE=13PVA1:ROI1:SizeX_RBV,YSIZE=13PVA1:ROI1:SizeY_RBV,PORT=OVER1,ADDR=0,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=13PVA1:,R=Over1:2:,NAME=ROI2,   SHAPE=1,O=Over1:,XPOS=13PVA1:ROI2:MinX_RBV,YPOS=13PVA1:ROI2:MinY_RBV,XSIZE=13PVA1:ROI2:SizeX_RBV,YSIZE=13PVA1:ROI2:SizeY_RBV,PORT=OVER1,ADDR=1,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=13PVA1:,R=Over1:3:,NAME=ROI3,   SHAPE=1,O=Over1:,XPOS=13PVA1:ROI3:MinX_RBV,YPOS=13PVA1:ROI3:MinY_RBV,XSIZE=13PVA1:ROI3:SizeX_RBV,YSIZE=13PVA1:ROI3:SizeY_RBV,PORT=OVER1,ADDR=2,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=13PVA1:,R=Over1:4:,NAME=ROI4,   SHAPE=1,O=Over1:,XPOS=13PVA1:ROI4:MinX_RBV,YPOS=13PVA1:ROI4:MinY_RBV,XSIZE=13PVA1:ROI4:SizeX_RBV,YSIZE=13PVA1:ROI4:SizeY_RBV,PORT=OVER1,ADDR=3,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=13PVA1:,R=Over1:5:,NAME=Cursor1,SHAPE=1,O=Over1:,XPOS=junk,                  YPOS=junk,                  XSIZE=junk,                   YSIZE=junk,                   PORT=OVER1,ADDR=4,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=13PVA1:,R=Over1:6:,NAME=Cursor2,SHAPE=1,O=Over1:,XPOS=junk,                  YPOS=junk,                  XSIZE=junk,                   YSIZE=junk,                   PORT=OVER1,ADDR=5,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=13PVA1:,R=Over1:7:,NAME=Box1,   SHAPE=1,O=Over1:,XPOS=junk,                  YPOS=junk,                  XSIZE=junk,                   YSIZE=junk,                   PORT=OVER1,ADDR=6,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=13PVA1:,R=Over1:8:,NAME=Box2,   SHAPE=1,O=Over1:,XPOS=junk,                  YPOS=junk,                  XSIZE=junk,                   YSIZE=junk,                   PORT=OVER1,ADDR=7,TIMEOUT=1")

# Create 2 color conversion plugins
NDColorConvertConfigure("CC1", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDColorConvert.template", "P=13PVA1:,R=CC1:,  PORT=CC1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")
NDColorConvertConfigure("CC2", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDColorConvert.template", "P=13PVA1:,R=CC2:,  PORT=CC2,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create a circular buffer plugin
NDCircularBuffConfigure("CB1", 20, 0, "PVA", 0, 500, 0)
dbLoadRecords("NDCircularBuff.template", "P=13PVA1:,R=CB1:,  PORT=CB1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=PVA")

# Create an NDAttribute plugin with 8 attributes
NDAttrConfigure("ATTR1", 20, 0, "PVA", 0, 8, 0, 0, 0)
dbLoadRecords("NDAttribute.template",  "P=13PVA1:,R=Attr1:,    PORT=ATTR1,ADDR=0,TIMEOUT=1,NCHANS=2048,NDARRAY_PORT=PVA")
dbLoadRecords("NDAttributeN.template", "P=13PVA1:,R=Attr1:1:,  PORT=ATTR1,ADDR=0,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=13PVA1:,R=Attr1:2:,  PORT=ATTR1,ADDR=1,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=13PVA1:,R=Attr1:3:,  PORT=ATTR1,ADDR=2,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=13PVA1:,R=Attr1:4:,  PORT=ATTR1,ADDR=3,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=13PVA1:,R=Attr1:5:,  PORT=ATTR1,ADDR=4,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=13PVA1:,R=Attr1:6:,  PORT=ATTR1,ADDR=5,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=13PVA1:,R=Attr1:7:,  PORT=ATTR1,ADDR=6,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=13PVA1:,R=Attr1:8:,  PORT=ATTR1,ADDR=7,TIMEOUT=1,NCHANS=2048")
NDTimeSeriesConfigure("ATTR1_TS", 20, 0, "ATTR1", 1, 8)
dbLoadRecords("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/db/NDTimeSeries.template",  "P=13PVA1:,R=Attr1:TS:, PORT=ATTR1_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=ATTR1,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")

# Create an FFT plugin
NDFFTConfigure("FFT1", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDFFT.template", "P=13PVA1:, R=FFT1:, PORT=FFT1, ADDR=0, TIMEOUT=1, NDARRAY_PORT=PVA, NAME=FFT1, NCHANS=1024")

# Create 2 Codec plugins
NDCodecConfigure("CODEC1", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDCodec.template", "P=13PVA1:, R=Codec1:, PORT=CODEC1, ADDR=0, TIMEOUT=1, NDARRAY_PORT=PVA")
NDCodecConfigure("CODEC2", 20, 0, "PVA", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDCodec.template", "P=13PVA1:, R=Codec2:, PORT=CODEC2, ADDR=0, TIMEOUT=1, NDARRAY_PORT=PVA")

set_requestfile_path("./")
set_requestfile_path("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/ADApp/Db")
set_requestfile_path("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/areaDetector-R3-7/ADCore/iocBoot")
set_savefile_path("./autosave")
set_pass0_restoreFile("auto_settings.sav")
set_pass1_restoreFile("auto_settings.sav")
save_restoreSet_status_prefix("13PVA1:")
dbLoadRecords("/opt/epics/base-7.0.4/../modules/synApps_6_1_epics7/support/autosave-R5-10/asApp/Db/save_restoreStatus.db", "P=13PVA1:")

# Optional: load NDPluginPva plugin
#NDPvaConfigure("PVA1", $(QSIZE), 0, "$(PORT)", 0, $(PREFIX)Pva1:Image, 0, 0, 0)
#dbLoadRecords("NDPva.template",  "P=$(PREFIX),R=Pva1:, PORT=PVA1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
# Must start PVA server if this is enabled
#startPVAServer

# Optional: load ffmpegServer plugin
#ffmpegServerConfigure(8081)
#ffmpegStreamConfigure("FfmStream1", 2, 0, "$(PORT)", 0, -1, 0)
#dbLoadRecords("$(FFMPEGSERVER)/db/ffmpegStream.template", "P=$(PREFIX),R=ffmstream1:,PORT=FfmStream1,NDARRAY_PORT=$(PORT)")
#ffmpegFileConfigure("FfmFile1", 16, 0, "$(PORT)", 0, -1, 0)
#dbLoadRecords("$(FFMPEGSERVER)/db/ffmpegFile.template", "P=$(PREFIX),R=ffmfile1:,PORT=FfmFile1,NDARRAY_PORT=$(PORT)")

# Optional: load NDPluginEdge plugin
#NDEdgeConfigure("EDGE1", $(QSIZE), 0, "$(PORT)", 0, 0, 0, 0)
#dbLoadRecords("$(ADPLUGINEDGE)/db/NDEdge.template",  "P=$(PREFIX),R=Edge1:, PORT=EDGE1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
#set_requestfile_path("$(ADPLUGINEDGE)/edgeApp/Db")

# Optional: load NDPluginCV plugin
#NDCVConfigure("CV1", $(QSIZE), 0, "$(PORT)", 0, 0, 0, 0, 0, $(MAX_THREADS=5))
#dbLoadRecords("$(ADCOMPVISION)/db/NDCV.template",  "P=$(PREFIX),R=CV1:, PORT=CV1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
#set_requestfile_path("$(ADCOMPVISION)/adcvApp/Db")

# Optional: load NDPluginBar plugin
#NDBarConfigure("BAR1", $(QSIZE), 0, "$(PORT)", 0, 0, 0, 0, 0, $(MAX_THREADS=5))
#dbLoadRecords("$(ADPLUGINBAR)/db/NDBar.template",  "P=$(PREFIX),R=Bar1:, PORT=BAR1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
#set_requestfile_path("$(ADPLUGINBAR)/barApp/Db")

# Optional: load scan records
#dbLoadRecords("$(SSCAN)/sscanApp/Db/scan.db", "P=$(PREFIX),MAXPTS1=2000,MAXPTS2=200,MAXPTS3=20,MAXPTS4=10,MAXPTSH=10")
#set_requestfile_path("$(SSCAN)/sscanApp/Db")

# Optional: load sseq record for acquisition sequence
#dbLoadRecords("$(CALC)/calcApp/Db/sseqRecord.db", "P=$(PREFIX), S=AcquireSequence")
#set_requestfile_path("$(CALC)/calcApp/Db")

# Optional: load devIocStats records (requires DEVIOCSTATS module)
#dbLoadRecords("$(DEVIOCSTATS)/db/iocAdminSoft.db", "IOC=$(PREFIX)")

# Optional: load alive record (requires ALIVE module)
#dbLoadRecords("$(ALIVE)/aliveApp/Db/alive.db", "P=$(PREFIX),RHOST=192.168.1.254")

# Set the callback queue size to 5000, up from default of 2000 in base.
# This can be needed to avoid errors "callbackRequest: cbLow ring buffer full".
callbackSetQueueSize(5000)
set_requestfile_path("/opt/epics/modules/synApps_6_1_epics7/support/areaDetector-R3-7/pvaDriver/iocs/pvaDriverIOC/../../pvaDriverApp/Db")
iocInit()
Starting iocInit
############################################################################
## EPICS R7.0.4
## Rev. 2023-03-16T10:56-0700
############################################################################
reboot_restore: entry for file 'auto_settings.sav'
reboot_restore: Found filename 'auto_settings.sav' in restoreFileList.
*** restoring from './autosave/auto_settings.sav' at initHookState 6 (before record/device init) ***
reboot_restore: done with file 'auto_settings.sav'

reboot_restore: entry for file 'auto_settings.sav'
reboot_restore: Found filename 'auto_settings.sav' in restoreFileList.
*** restoring from './autosave/auto_settings.sav' at initHookState 7 (after record/device init) ***
reboot_restore: done with file 'auto_settings.sav'

2023/03/23 22:36:22.183 pvaDriver::connectPv exception initializing monitor: 0 or empty channel name
cas warning: Configured TCP port was unavailable.
cas warning: Using dynamically assigned TCP port 38059,
cas warning: but now two or more servers share the same UDP port.
cas warning: Depending on your IP kernel this server may not be
cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
iocRun: All initialization complete
2023-03-23T22:36:22.214 ServerContext configured with no Providers will do nothing!

# Silence a very chatty ASYN_TRACE_FLOW
# Remove this if performance testing
#dbpf 13PVA1:cam1:PoolUsedMem.SCAN Passive
# save things every thirty seconds
create_monitor_set("auto_settings.req", 30, "P=13PVA1:")
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
epics> auto_settings.sav: 1273 of 1273 PV's connected

Missing NULL test of NTNDArray::wrap()

NTNDArray::wrap() can return NULL. If for some reason it does, eg. I give it a somehow "incompatible" definition, then SIGSEGV follows.

NTNDArrayConverter converter(NTNDArray::wrap(update->pvStructurePtr));
NTNDArrayInfo_t info;
try
{
info = converter.getInfo();
}
catch(...)
{
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s::%s failed to get info from NTNDArray\n",
driverName, functionName);
monitor->release(update);
continue;
}

Also, it is bad form to swallow exception messages like this. I see no reason to catch anything other than std::exception. If you ever find that PVD or PVA throws something which doesn't derive from std::exception, then please report this as a bug.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.