Offline Discussions



Step 1: Log into a cluster

At DayaBay Site:

 % ssh -AX 
 % ssh -X farm1.dyb.local  (or farm2) 


 % ssh -X 


% ssh -X 

For the Brave: Install NuWa on your own computer

Step 2: Load software

Find the installation you want to use:

At DayaBay:

% export NUWAROOT=/home/dyb/dybsw/NuWa/NuWa-trunk


% export NUWAROOT=/home/dyb/dybsw/NuWa/NuWa-trunk


% module load subversion/1.5.0 
% export NUWAROOT=/common/dayabay/releases/NuWa/trunk/NuWa-trunk

Note: The softlink "trunk" points to the latest trunk release on PDSF. If you want to make sure you always use the same trunk release, you should specify the actual path (e.g. /common/dayabay/releases/NuWa/trunk_20100308/NuWa-trunk)

Forthe above run the following:

% pushd $NUWAROOT
% source
% cd dybgaudi/DybRelease/cmt
% source
% popd

At RACF just do:

% nuwaenv -r trunk

Step 3: Find Raw Data

DryRun data At DayaBay (farm1.dyb.local):


MiniDryRun data At DayaBay (farm1.dyb.local): (Why is this data in my home account?)

% ls /dyb/home/dandwyer/data
% ls /home/dyb/rawdata      (broken!)


% ls /dyb/dybd07/ingest_data/data/exp/dayabay/2010/TestDAQ/NoTag/
0102  0105  0107  0109  0111  NoTag_meta.xml
0103  0106  0108  0110  0112  unzip.log


% ls /eliza7/dayabay/data/exp/dayabay/2009/TestDAQ/NoTag/
1001  1021  1118  1123	1203  1210  1213  1219	1222  1225  1230
1002  1104  1119  1127	1204  1211  1214  1220	1223  1226  1231
1006  1106  1120  1202	1209  1212  1215  1221	1224  1228  NoTag_meta.xml
% ls /eliza7/dayabay/data/exp/dayabay/2010/TestDAQ/NoTag/
0102  0103  0105  0106	0107  0108  0109  0116	0117  0118  NoTag_meta.xml

This link for RACF at BNL.

An useful example file is, which you can find in the 0716 directory on PDSF and the 0717 at IHEP. (Yes, the filing by date needs to be fixed so it is uniform!)

Step 4: Run an Analysis Example

Some simple example scripts are provided in dybgaudi/DybExamples/Quickstart

Example 1: Print raw ADC/TDC data of one event to screen, make one histogram

% -A None -n 1 -m"Quickstart.PrintRawData" /path/to/data/

Example 2: Print raw ADC/TDC data of all events to screen, make one histogram

% -A None -n -1 -m"Quickstart.PrintRawData" /path/to/data/

Example 3: Access PMT ID and positions, draw hit pattern on PMTs

% -A None -n -1 -m"Quickstart.PmtInfoExample" /path/to/data/

Example 4: Dump ADC/TDC data to a simple ROOT tree

% -A None -n -1 -m"Quickstart.RawEventTree" /path/to/data/

Miao has provided a more advanced C++ example algorithm; see DocDB-4480 [1].

Step 5: Make your own Analysis Script

Copy existing script to your own directory, change it:

% mkdir ~/mywork
% cd ~/mywork
% cp $QUICKSTARTROOT/python/Quickstart/
% emacs &

Modify script. Add new histograms inside 'initialize()' function. Fill data into histograms inside 'execute()' functions.

Run your script: (remember to remove 'Quickstart.' from name on command line)

% -A None -n -1 -m"PrintRawData" /path/to/data/

Step 6: Learn about the raw data

The ReadoutHeader contains one 'Triggered' Readout of one detector. One Readout contains all the channels for that trigger. Each channel has the TDC/ADC data (hit time and charge) from the hits on one PMT.

Here are some comments taken from the PrintRawData example script:

Readout Header

       # Access the Readout Header.  This is a container for the readout data
       readoutHdr = evt["/Event/Readout/ReadoutHeader"]
       if readoutHdr == None:
           self.error("Failed to get current readout header")
           return FAILURE


       # Access the Readout.  This is the data from one trigger.
       readout = readoutHdr.readout()
       if readout == None:
           self.error("Failed to get readout from header")
           return FAILURE

Detector ID

       # Get the detector ID for this trigger
       detector = readout.detector()"Detector Name: "+detector.detName())

Trigger info

       # Trigger Type: This is an integer of the type for this trigger"Trigger Type: "+str( readout.triggerType() ))
       # Trigger Number: A count of the trigger, according to the DAQ"Trigger Number: "+str( readout.triggerNumber() ))

Note, trigger number runs from 0-255 and then loops around again. See Trac ticket #412 for details. To get full number use:

       # Trigger Time: Absolute time of trigger for this raw data
       triggerTime = readout.triggerTime()
       # Trigger Time [Seconds]: Trigger time in seconds from some day in 1990"Trigger Time [Seconds part]: "
                 +str( triggerTime.GetSec() ))
       # Trigger Time [Nanoseconds]: Nanoseconds part of trigger time"Trigger Time [Nanoseconds part]: "
                 +str( triggerTime.GetNanoSec() ))
       # Full Trigger Time: Seconds + nanoseconds
       # Warning: When you add this together, it will lose some precision."Full Trigger Time: "
                 +str( triggerTime.GetSec()
                       +triggerTime.GetNanoSec()*1.0e-9 ))

Loop Over Channel Data

       # Loop over each channel data in this trigger
       adcSum = 0
       for channelPair in readout.channelReadout():
           channel = channelPair.second
           channelId = channel.channelId()
           # The channel ID contains the detector ID, electronics board number,
           # and the connector number on the board.
 "Channel ID:"
                     +" detector="
                     +" board="
                     +" connector="

TDC Data

           # TDC data for this channel
           # The TDC is an integer count of the time between the time
           # the PMT pulse arrived at the channel, and the time the
           # trigger reads out the data.  Therefore, a larger TDC =
           # earlier time.  One TDC count ~= 1.5625 nanoseconds.
           for tdcIdx in range( channel.size() ):
               tdc = channel.tdc( tdcIdx )
     "TDC value: "+str( tdc ))

ADC Data

           # ADC data for this channel
           # The ADC is an integer count of the charge of the PMT
           # pulse.  It is 12 bits (0 to 4095).  There are two ADCs
           # for every PMT channel (High gain and Low gain).  Only
           # the high gain ADC is recorded by default.  If the high
           # gain ADC is saturated (near 4095), then the low gain ADC
           # is recorded instead.
           # For the Mini Dry Run data, one PMT photoelectron makes
           # about 20 high gain ADC counts and about 1 low gain ADC
           # count.  There is an offset (Pedestal) for each ADC of
           # ~70 ADC counts (ie. no signal = ~70 ADC, 1 photoelectron
           # = ~90 ADC, 2 p.e. = ~110 ADC, etc.)
           # The ADC clock is a record of the clock cycle which had
           # the 'peak' ADC.
           # ADC Gain: Here is a description of ADC gain for these ADC values
           #  Unknown = 0
           #  High = 1
           #  Low = 2
           # Loop over each ADC value
           for adcIdx in range( channel.size() ):
               adc = channel.adc( adcIdx )
               adcClock = channel.adcCycle( adcIdx )
               adcGain = channel.adcRange( adcIdx )
     "ADC value: "+str(adc)
                         + " (peak cycle: "+str( adcClock )+","
                         + " gain: "+str( adcGain )+")")
               # Add to total ADC sum for this trigger
               if adcGain == 1:
                   adcSum += adc
               elif adcGain == 2:
                   # Adjust low gain adc to high gain scale
                   adcSum += adc * 20

Links to data class docs

Detailed software documentation for these data classes can be found here:

Here is a link to the NuWa User Manual:

Mini-dry run

Known Problems

  • Use '-A None' option when running on Mini Dry Run data files
  • You must set the Cable Map and Calibration data .txt files in your analysis scripts of raw data files. See Example #2 script above. Zhe and Daniel have made this automatic for the Cable Map. Further work is required for the FEE and PMT calibration tables.
    • (Update by Zhe) This automatic function is already committed to nuwa trunk. Static cable service can pick the right cable data. Static calib service also have the ability to pick the right calibration data. But because the mini dry have wild trigger time virance, so only two calib data files can work. In case you want to use a specific, please assign one in your python script.
    • The default parameter files are specified in DataModel/DataSvc/share/Master.CableMap.txt, Master.feeCalibMap.txt and Master.pmtCalibMap.txt.
  • There are two bugs in the trigger electronics which gives the wrong time in the raw data. First, all the times are in the 1990s and are reset each time the DAQ was reconfigured. Second, the trigger electronics wrote times assuming 61 seconds in a minute and 61 minutes in an hour. See Zhe's presentation.
  • The example scripts above work with NuWa-1.5.0; they must be modified to work with the current trunk. Scripts in Quickstart package work with current trunk.

Dry Run

Known Problems

  • Run 1711: CCG was not correctly initialized with right time. User need to add a correct delta T (July 201 - Jan,1st 1970) when asking cable map and calibration constant. For example, for the QuickStart.RawEventTree script:
if roHdr.timeStamp().GetSec() < 1e9:  roHdr.context().GetTimeStamp().Add(1.2768e9)  # Line to be added
svcMode = ServiceMode( roHdr.context(), 0 )   # Construction of Service Mode