10/1
Email to Walt (& Ken):
Questions:
1) Runfile:
* What do the codes mean, i.e. < RB cc row_len > ##
-> Ans < var card param > data... (in runfile formating on MAS wiki.)
* What/where are the serial numbers that allow us to synch the data files with the antenna layer information?
-> Ans Header word 10 in MAS flat-field format.
2) Datafile:
* What is the output format? DAS flat-file?
-> Ans MAS flat-field format + configuration information in pseudo-XML runfiles. MCE flat-file wiki page.
3) MAS
* How does the MAS know when to stop writing and close a data file?
-> Ans Currently, you must specify the number of frames to record when starting acquisition. Of course, with network port output instead of file output, it would be much better to have acquisition continue indefinitely once it's started.
* How does the MCE get a time signal?
-> Ans from the sync box, which is external to the MCE.
* What OS is the MCE/MAS run on?
-> Ans OS = Ubuntu 6.06 or 7.10.
* What hardware?
-> Ans there is a list of recommended PC motherboards on the MCE wiki.
* Where is PutData() defined? It is used in mas2dir.c
-> Ans This is part of the dirfile library I mentioned earlier. You will need to install it before you can generate dirfiles. Library by Ted Kisner. However, this may or may not be useful to you if you're going directly to network port output.
4) Time Synch
* How does it synch this with the antenna layer?
-> Ans match serial number in MCE (from synch box) with the gcp serial number. Gcp serial number comes from when a DataValid trigger from the synch box is received by the BLASTbus PCI controller card.
Thus the synch box sends out a time stamp to the MCE, which is recorded in the data frame (how?), and also to the gcp accompanied by a DV trigger. This is received by the BLASTbus PCI controller card. These two time stamps are then matched in the gcp mediator when the data frame from the MCE arrives.
From Walt:
There are a few different ways that you could go about this synchronization, and it will be largely up to you to choose the most convenient and robust approach. This is not entirely straightforward because of the need to accumulate some number of MCE "fast frames" to form one GCP "slow frame." That is, the actual bolometer timestreams will become fast registers in GCP, while some of the header and settings information may become slow registers. The sync box time stamp will also be a fast register, since each sync generates a single MCE frame. One possibility is to fix the mapping of sync box stamps to GCP slow frames. For instance (assuming the sync box stamps are consecutive integers), let every stamp divisible by 100 be the start of a new GCP frame. This has the advantage of making it easy to start packing MCE data into the GCP stream in a deterministic way once the frames start arriving. But the details will likely depend on how big a delay there is between the sync box signal and the MCE frames arriving at the GCP, and on the level of sophistication of the network stream (e.g. how does the MCE computer handle fast and slow registers?)
Email to Clem, John, Eric, Walt, Ken:
Options:
1) Use the existing MuxReadoutSoftware. This would require puting a new layer of code on top of the mas code that had identical output to the DIOServer and HardwareManagerServer
- DIOServer: two separate connections, one for data (binary) and one for runfile information (xml).
- HardwareManagerServer: one connection for sending and receiving commands (xml).
2) Something completely new.
Idea: make the MuxReadoutSofware code work first, then improve it to be something more elegant.
Questions:
- Who will do the job of writing the MAST code? Walt? Me?
- Dummy MCE output.
- Who at UBC can I email with questions about the MCE?
- What is the archive format? Dirfiles? Something else? I assume the code to do this already exists in gcp?
- What is the mapping from MAS output to archive registers, if different?
- Need to define interface over net between MAS Transfer (MAST).
10/6
SPT holography Daemon: simplified HardwareManager code:
- > Spt wiki -> Brouse Source -> Holography -> Daemon
Check out new version of BICEP gcp code:
cvs -d bicep0.caltech.edu:/home/bicep0/cvsroot checkout -r working14Feb gcp
SPT reference code:
directory:
spt.uchicago.edu:~/home/sptdaq/gcpDeploy/
Directories in spt-gcp that are not in bicep-gcp:
- bin -> executable scripts
- config -> ??
- doc -> looks like documentation
- muxutil -> runs HardwareManager, Mux, XML, and TCP things. Important.
- pgutil -> plotting code
- receiver -> Important
- runlogs -> output logs from runs
Files relevant to the DIOServer:
gcp/receiver/specific/MultiThread/DIOServer_Session.h
gcp/receiver/specific/MultiThread/DIOServer_Support.h
gcp/receiver/spt/DioClient.cc
gcp/muxutil/*
mediator/specific/Test/tSession.cc_save
Questions about DIO:
1) Where is Utilities/DIOClient.h ?
2) Where is $(HOME)/MuxReadoutSoftware ?
Copy entire gcp/receiver/ and gcp/muxutil/ foulders over to gcp_bicep2/
Compile gcp code:
Try:
kstory@bicep0:gcp/$ pwd /export/home/bicep0/kstory/gcp_bicep2/gcp kstory@bicep0:gcp/$ make -> Lots of errors.
Add the following line to .bashrc:
GCP_DIR='/home/bicep0/kstory/gcp_bicep2/gcp/control/'
Old code is still working. try moving old code to 8.08_gcp, and new code to ~/gcp/
failure:
make[4]: Entering directory `/export/home/bicep0/kstory/gcp/control/code/unix/libunix_src/bicep' Executing depend rule make[4]: *** No rule to make target `/export/home/bicep0/kstory/gcp_bicep2/gcp/gcp/util/common/AntNum.h', needed by `rtcnetcoms.o'. Stop. make[4]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code/unix/libunix_src/bicep' note, the directory gcp_bicep2/gcp no longer exists.
Try again from scratch:
Check out gcp code from CVS and compile:
cvs -d bicep0.caltech.edu:/home/bicep0/cvsroot checkout -r working14Feb gcp kstory@bicep0:~$ cd gcp kstory@bicep0:gcp$ make
Error:
make[4]: Entering directory `/export/home/bicep0/kstory/gcp/control/code/unix/libscan_src' Executing depend rule make[4]: *** No rule to make target `/scr/eml/projects/bicep/gcp/control/code/unix/libunix_src/common/input.h', needed by `scan.o'. Stop. make[4]: Leaving directory `/export/home/bicep0/kstory/gcp/control/code/unix/libscan_src' make[3]: *** [make_libscan] Error 2
Following my previous posting about errors;
Remove ./control/code/unix/libscan_src/Makefile.rules
kstory@bicep0:gcp$ mv control/code/unix/libscan_src/Makefile.rules BADMakefile.rules kstory@bicep0:gcp$ make
It now compiles!
add new runlogs directory.
Copy over simple startup programs:
kstory@bicep0:gcp$ mkdir runlogs kstory@bicep0:bicep$ cp ~/8.08_gcp/misc/scripts/bicep/myclose . kstory@bicep0:bicep$ cp ~/8.08_gcp/misc/scripts/bicep/mysimpleStartup .
Program now runs.
For after lunch:
- make a "Reference Notes" section on webpage for things like grep, checking out gcp from cvs, etc. -> Done
- email Clem, John Carlstrom about bookshelves.
New Idea from Clem:
Write out the simplest possible input mechanism over a TCP/IP connection to get the gcp to read in something new.
To Do:
- Make gcp compile and run -> Done
- Find what antenna input to model
- Write new antenna input system
- Write dummy input program that connects over a TCP/IP connection.
First look into TriWave
Call it TriWave for the triangle wave that I hope to send over it.
Thought: I might need root privelages to run any of the antenna code. This could be a problem.
From Erik Leitch's short introduction to gcp, he says "bicepAntennaControl must be run as root, because the thread prioritizing requires root priveleges. On bicep1/3, bicep can sudo these commands. On bicep2, you have to be root."
First, try copying GpsBoard:
~/gcp/antenna/control/bicep/GpsBoard.h
~/gcp/antenna/control/bicep/GpsBoard.cc
Need a TriWave class definition:
~/gcp/antenna/control/bicep/TriWave.h
~/gcp/antenna/control/bicep/TriWave.cc
10/8
Meet with Clem:
1) Real code:
Don't want to modify MCE code too much; I will have to keep thinking about this.
2) Toy Code:
Plug into Antenna.
Model after either Tipper or Weather.
Make new register in antenna0.
Change register map file:
control/code/unix/libunix_src/bicep/specificregs.c
Add a register map, call it KyleWave.
host=localhost.
Linux:
locate
nice
For Today:
- Modify specificregs.c to get KyleWave to show up. -> Done
- Try to get Antenna to run without root password. -> Done
- Look into configuration file that the Viewer complains about. -> ??
- Look at Tipper and Weather as models for new KyleWave.
Add register kyleWave to antenna0
- Add new RegBlockTemp in specificregs.c
- Add the new RegBlockTemp into the RegBoardTemp in specificregs.c
- Add a .page file in control/conf/bicep/
specificregs.c
Add a new RegBlockTemp kyleWave[].
/**......................................................................
* Create a new toy board: KyleWave
*/
static RegBlockTemp bicepKyleWave[] = {
RegBlockTemp("Kyle's toy board: feeds triangle wave.",
"kyleWaveVal", REG_DOUBLE|REG_PREAVG),
};
Add kyleWave to the RegBoardTemp:
static RegBoardTemp bicep_antenna_boards[] = {
...
{"kyleWave", bicepKyleWave, ARRAY_DIM(bicepKyleWave), {0x0},
"Kyle's Toy register"},
};
common/regtemplate.h
Definitions of the rules for doing this.
This all compiles!
Try to run using mySimpleStartup.
My KyleWave shows up!
In Viewer:Configure-> AddPage
In Page: right Click-> register-> list-> antenna0-> kyleWave
Fix Antenna:
remove sudo and nice -20 -> Fixed!!
Look into configuration file error.
Error reading configuration file: /home/bicep0/kstory/gcp/control/conf/gcp//stat.page couldn't read file "/home/bicep0/kstory/gcp/control/conf/gcp//stat.page": no such file or directory
The directory is defined in gcp/control/conf/bicep/
However there is not stat.page in this file, nor any viewer.init type files.
Looking at Tipper code
TipperClient.h
Constructor, destructor
fields:
BicepShare* share_
RegMapBlock* utcBlock_, tauBlock_, tAtmBlock_
methods:
readServerData(gcp::util::NetHandler&)
TipperClient.cc
10/13
Looking at Tipper code in bicep gcp
Working on looking at how Tipper works.
BicepShare
antenna/control/bicep/BicepShare.cc
Class BicepShare
Class BicepRegDb -> access register database and its shacow registers
findRegMapBoard( boardName );
private:
friend class BicepShare;
RegMap *regmap_
Class BicepClock -> Used by BICEP UTC clock
Class BicepAstrom -> Astronomy object
Class BicepPmacLock
str controlHost_
*regdb_
*clock_
*astrom_
pmac_lock_
Tfp gps_
_Board.cc_
Class Board
RegMapBoard board_
BicepShare* share_
bool hasBoard_
RegMapBlock* findReg(char* name){
block=find_RegMapBoard_Block(board_, name)
}
Still not sure where BicepShare->findReg("board","block") is defined.
TipperClient.cc
Constructor
{ aBlock_ = share_->findReg("tipper", "a") }
void TipperClient::readServerData(gcp::util::NetHandler& handler)
{
handler.getReadStr()->stargGet(&size);
handler.getReadStr()->getChar(...);
handler.getReadStr()->endGet();
tipperData_.desearialize(bytes_);
share_->writeReg(tauBlock_, tipperData_.tau_);
TipperData defined in "util/common/TipperClient.h, cc"
TipperReader.cc
TipperData data_;
TimeVal timeOut_;
BicepShare* share_;
RegMapBlock* utcBlock_;
RegMapBlock* tauBlock_;
RegMapBlock* tAtmBlock_;
void getMostRecentData();
void packData();
RUN_FN(Tipperreader::runFn) -> calls tipperReader::run()
void TipperReader::run() {
getMostRecentData();
packData();
}
void TipperReader::getMostRecentData() {
fp=fopen("SmmTip.log","r");
while(fgets(line, 100, fp) !=0); -> read from fp into line
fclose(fp);
sscanf(line, "...",&data_.var); -> read variables from line into data_
}
Write KyleWave modeled after Tipper code
KyleWaveClient.h
share_;
waveValBlock_;
TimeVal timeOfLastUpdate_;
TimeVal updateInterval_;
void readServerData(NetHandler& handler);
KyleWaveClient.cc
KyleWaveReader.h
KyleWaveReader.cc
gcp/util/common/ KyleWaveData.cc, h
Everything important happens in the Client class. Connecting across a network connection, read, write...
Questions:
1) tipperData_.deserialize(bytes_); -> Called from NetStruct class. Do I need a separate data file?
2) in util/common/, constructor has Client(spawnThread, host, TIPPER_SERVER_PORT)
3) what is "SmmTip.log" found in TipperReader.cc? What is a smb connection?
10/20
- I have a new computer!!
Toy TCP/IP code
I found a simple example of TCP/IP code here:
Programming IP Sockets on Linux, Part One
There are some TCP/IP ports that are reserved
Well Known Ports: 0-1023, requires administrative privileges.
Registered Ports: 1024 - 49151
Dynamic and/or Private Ports: 49152 - 65535
Wikipedia Port numbers
Run my toy code using port 49160:
In terminal Server: kstory@spudws2:gnosisExample> ./TCPechoServer 49160 In terminal Client: kstory@spudws2:gnosisExample> ./TCPecho 128.135.70.214 "How about that fee lunch?" 49160 Server: Client connected: 128.135.70.214 Client: Received: How about that fee lunch?
Alternate object oriented Toy TCP/IP code:
Source: Practical C++ Sockets
Meet with Ken
Two ideas:
1) Make mce a new board in the antenna
2) Plug straight into the Mediator.
It looks like following the old bolometer path should work, if we write a daemon on the mce side that maintains a connection to the gcp and forwards data.
This works as follows:
- mce writes out to a "file" which is actually a pipe into the daemon.
- The daemon maintains a UDP connection to the gcp.
- The daemon sends the mce data to the gcp through the UDP
- The gcp code closely resembles the current bolometer readout code. It collects the data and maintains a queue in the Antenna layer to synchronize data into data frames. These frames are then sent to the mediator.
- Everything else remains the same.
Track this process through:
control/code/unix/libunix_src/bicep/specificregs.c
Look at RegBlockTemp bicepBolo[]:
cosine
sine
mag
phase
voltage
frequency
mode
received
This is a board in the RegBoardTemp bicep_antenna_boards[]
gcp/antenna/control/bicep/NetDataParse.cc
NetDataParse : Board
received_, cosine_, sine_, voltage_, mode_, etc.
init_bolo_registers() -> routine for handling bolometer data
read_bolo_sample() -> get data out of NetDataBoard
for(bindex=0; bindex
calculate cosine[], sine[], sAvg[], cAvg[], quadsum[], thermalControlVals[], phase[]
}
}
// store cosine comp of the AC bias as the second element of this register
data->words2components2(data->box[BOLO_BIAS_OFFSET].
sdata[BOLO_AC_BIAS_CHAN_READ], &s, &c, VMAX);
voltage[NSAMPLESPERFRAME + nsample] = c;
// store teh sin comp of the AC bias as the third element of this register
voltage[2*NSAMPLESPERFRAME + nsample] = s;
store frequency[], mode[], received[]
fake_bolo_sample()
pack_bolo_frame() {
share_->write(field_, field) where field = {received, cosine, sine, quadsum, voltage, frequency, mode, phase}
init_type_registers()
read_type_sample()
pack_type_frame() -> for type = {fridge, rotator, time, datasys, auxiliary, dewar, level, cal}
gcp/antenna/control/bicep/NetDataBoard.cc
NetDataBoard - class for reading/writing data and messages to and from BICEP's UDP-based data acquisition system.
UDPSocket* socket
struct DataSystemBox
u char id[], sn[], rev[], seq[], vcc[], vee[], vdd[], temp[], sdata[NCHAN][BYTES_PER_WORD], box[s]
u int crc
u char last_cmd, last_lia_cmd, guard[]
struct BoxData
int sequence_
float temperature_, vcc_, vdd_, vee_, id_, serial_, revision_
std::vector
NetDataBoard:
3 constructors:
NetDataBoard::NetDataBoard(int port, int n) -> sets up a "reader" NetDataBoard
NetDataBoard::NetDataBoard(int port, int n, char hostname[] ) -> sets up a "writer" NetDataBoard
NetDataBoard::NetDataBoard()
init() -> initialization tasks that are common to all constructors.
settimeout() -> set timeout for read/write/listen/command operations
// Read Data
flush()
read()
for(unsigned i=0;i
}
return n;
read(unsigned iBox) -> read data from a single box.
UDPSocket& sock = socket[iBox]
unsigned nReady = sock.nByte();
unsigned nRead = sock.read( (char*)(&(box[iBox])), dataSystemSize_);
// Write Data
write()
for(unsigned i=0;i
write(unsigned iBox)
socket[iBox].write( (char*)(&(box[iBox])), sizeof(DataSystemBox) );
// Print Data
various functions
// Parse Data
words2components(unsigned char words[], double* s, double* c, double vmax )
// Opposite of components2words:
// Read in back-to-back 24-bit integer words, and return them as cosine and sine components, scaled into the range defined by [-vmax, vmax].
components2words(unsigned char words[], double* s, double* c, double vmax )
// Opposite of words2components:
// Read in cosine and sine complonents, c and s. Rescale them into the range [0, max]. Then return them as back-to-back 24-bit integer words.
// Simulate Data
fake(unsigned long seq)
// Create a single frame of fake data, which may then be sent via write(). This is useful during testing.
// The sequence number is essentially the time axis, so the seq argument should be incremented each time fake(seq) is called.
// Send a Command
command(unsigned int channel, char protocol, char command, const char* format, ... )
...
for(unsigned i=0;i
command(unsigned iBox, unsigned int channel, char protocol, char command, const char* format, ... )
...
do {
ret=socket[iBox].write(msgPtr + total, len-total);
total += ret;
} while(total < len)
// Set/get Housekeeping Voltages
// Listen for a Command
lisen()
for(unsigned i=0;i
// Hash
// Parse a Command
commandparse(...)
seq(unsigned iBox) -> Return the file descriptor associated with a specific box
10/22
Advice from Erik Leitch
Yes, I would start with the BICEP version of gcp for BICEP2. The tracking code has been completely modified for SPT.
These will be the same between BICEP and BICEP2, presumably.
The details of how this should be done depend on what the data acquisition model is, and where that process should live:
is the receiver polled for data, or will data be automatically sent at some fixed rate by the receiver? My understanding is
that the data for BICEP2 will come from the data acquisition computer (the MCE) already timestamped, and at some regular rate?
If so, then the mediator should just listen on a socket for connection requests from the receiver data server, and set up to read
data as they arrive. The creation and archiving of data frames will have to be keyed to a software timer synchronized with absolute time.
For BICEP, the model was that the arrival of data from the receiver electronics was the fundamental clock. The GPS card was
read out whenever data happened to arrive over a UDP socket connection, and the accumulation of N fast samples was what defined a data
frame (and drove the data flow through the control system). If the electronics stop sending data, or the connection to the electronics
is lost, no data flow through the system.
For SPT (and SZA), the model is that data frames are generated in synch with absolute time; data from the receiver (or correlator)
arrive on absolute half-second time boundaries and are stored in the appropriate data frame for that time stamp. If the receiver
(or correlator) goes offline, data continue to flow through the system.
I imagine that BICEP2 will be more like the second model, which will also necessitate some changes to the mediator Scanner
thread, which handles receipt and collation of data from multiple sources into a single data frame.
How will you synchronize telescope positional information with the data acquisition? The current BICEP control system just
reads out the telescope positions from the pmac whenever data arrive. This will presumably have to be modified to be keyed to a
software timer (or interrupt) synchronized with absolute time.
If no real-time synchronization has to happen between the positional information and the receiver data, then probably the receiver
data acquisition should be modeled on the BICEP antenna data acquisition (bicepAntennaControl).
That program establishes a socket connection with bicepMediator, stores data into a 'frame' that represents all of the antenna
data for a given time interval, then sends that frame back to bicepMediator where it is integrated into a larger data frame that represents a
snapshot of all system data for the same time interval, which is then sent to bicepControl for archiving.
Another example of the same basic structure is the frame grabber, which is a simpler example since it doesn't contain so many
extraneous threads, but doesn't package its data in a data frame the way the antenna process does (and also sends its data back directly to
bicepControl instead of bicepMediator). But the basic structure of all of them is the same:
a Master thread, that spawns all the other threads, and handles messaging with external processes
- a Scanner thread, spawned by the Master, that handles sending data back to another process
- a Control thread, spawned by the Master, that handles commands received from external processes.
- a Signal thread, that handles signals and timers
The structure is probably easiest to see by looking at
gcp::grabber::Master.cc.
gcp::antenna::control::
AntennaMaster.cc is the antenna equivalent.
A corresponding hook will have to be written in gcp::mediator::Scanner to establish a connection with the server and process data frames
received from it. The class gcp::mediator::AntennaConsumerNormal accomplishes this for the antenna data.
The change to the mediator Scanner thread to enable creation of a data frame on a timer can be seen in commented-out code that I left in
place in gcp::mediator::Master::installTimers().
gcp/antenna/control/bicep/DataBase.cc
class DataBase
class Seq -> sequence numbers 0 through 9999
friend class AntennaRx
AntennaRx* parent_
NetDataBoard* data_
PmacBoard* pmac_
bool simData_
ThermalControl thermalControl_
NetDataParse* bolo_, fridge_, rot_, dewar_, timep_, datasys_, aux_, level_, cal_
struct FastReg -> a struct used for handling fast registers for the pmac
RegBlock* rcvdBlk_
std::vector
DataBase(AntennaRx* parent)
data_ = new NetDataBoard(parent_->dataport_ , NBOX);
pmac_ = new PmacBoard(share_, "pmac", parent_->simPmac());
addFastPmacRegs()
bufferTimeData(unsigned iSamp, int deltaMicroSeconds)
writeTimeData()
bufferPmacData(unsigned iSamp) -> read out regs from pmac
writePmacData()
addFastReg(std::string slowRegName, std::string fastRegName) -> add a fast pmac reg to be monitored
bufferBoxData(unsigned iSamp, unsigned received) -> buffer data for this sample
writeBoxData() -> write box data into the frame
bufferData((unsigned iSamp, unsigned received) -> calls bufferBoxData, bufferPmacData, bufferTimeData
writeData() -> calls writeBoxData, writePmacData, writeTimeData
initParsers() -> initializes NetDataParse fields (bolo_, fridge_, etc)
gcp/antenna/control/bicep/DataNew.cc
class DataNew
gcp::util::TimeVal timeOut_
static const unsigned fastTimeOutMilliSeconds_ = 30;
static const unsigned slowTimeOutSeconds_ = 1;
gcp::util::FdSet fdSet_
std::ofstream* fout_
DataNew(AntennaRx* parent, bool dumpData=false);
DataNew(bool simData, bool simPmac, bool simGps);
runTest1(), runTest2(), runTest3(), runTest4()
serviceMsgQ()
while(!stop) {
nready=select(fdSet_.size(), fdSet_.readFdSet(), NULL, NULL, timeOut_.timeVal());
calls data_->read(iBox)
seq = data_->seq(iBox) // get sequence number of this packet
various time synching stuff
incrimentSampleCount(unsigned& iSamp, unsigned received) -> incriment to next sample
processMsg(DataMst* msg) -> process a message received on the AntennaRx message queue
gcp/antenna/control/bicep/AntennaRx.cc
AntennaRx class will handle all receiver functions. This class instantiates proxy objects for all receiver subsystems, which can be served as COBRA distributed objects.
AntennaRx class
int dataport_, cmdport_
std::string cmdhost_
DataBase* dataTask_ -> pointer to the Data Task resources
CommandTask* commandTask_ -> pointer to the Command Task resources
AntennaMaster* parent_
THREAD_START(AntennaRx::startData) -> Data thread startup function
THREAD_START(AntennaRx::startCommand)
processMsg(AntennaRxMsg* msg) -> process a message received on the AntennaRx msg queue
sendTrackerRxMsg(rxId) -> Forward a message to the tracker task that we are changing frequencies
ANTENNARX_TASK_FWD_FN(AntennaRx::forwardDataMsg) -> Forward a message to the control task
ANTENNARX_TASK_FWD_FN(AntennaRx::forwardCommandMsg)
How data propagates through the Antenna Layer
- Scanner starts Antenna thread
- calls THREAD_START(AntennaRx::startData), which is defined in AntennaRx.cc
AntennaRx* rx = (AntennaRx*) arg;
rx->dataTask_->run();
- calls DataNew::run() { serviceMsgQ() }
- calls DataNew::ServiceMsgQ(), which watches for data from boxes. When data arrives over the UDP port, sets off a chain of events that eventually calls incrimentSampleCount, bufferPmacData, and bufferTimeData
- calls NetDataBoard::read(unsigned iBox), which read the actual socket.
- calls DataBase::bufferPmacData()
also DataBase::bufferTimeData()
- calls DataNew::incrimentSampleCount(unsigned& iSamp, unsigned received), which calls
bufferBoxData(iSamp, received) -> read new data into NetDataBoard* data_
if(iSamp== NSAMPLESPERFRAME)
writeData() -> writes to shared memory
- calls DataBase::bufferBoxData(unsigned iSamp, unsigned received)
- calls NetParseData::read_bolo_sample(unsigned nsample, NetDataBoard data, unsigned rcvd, double thermalControlVals)
reads data into double s and double c with the following command:
for(bindex...)
for(cindex...)
data->words2components2(data->box[bindex+BOLO_DATA_OFFSET].sdata[cindex], &s, &c, VMAX );
- DataBase::writeData(){
writeBoxData();
writePmacData();
writeTimeData();
}
- DataBase::writeBoxData()
bolo_->pack_bolo_frame(); // where bolo_ is of type NetDataParse*
other pack_type_frame() functions
- NetDataParse::pack_bolo_frame()
share_->writeReg(field_, field) // where field = {received, cosine, sine, quadsum, voltage, frequency, mode, phase}
share_ is of type BicepShare*
Current idea of mce integration
Plug Mce directly into the Mediator layer, similarly to the Antenna and Grabber. This will be implimented with a "receiver data server" that can be modeled after the Grabber, and/or the Antenna.
The mce data should have timestamps called "serial numbers" in the header file.
Take current Antenna code and remove code that polls the "box" UDP sockets, so that it just reads the PMAC position data periodically based on the system clock, which can be synchronized to GPS time using the NTP protocol. Q: necessary precision of the synchronization?
Set up a message queue in the Mediator that collects data and position information for a specific amount of time (1 sec?). It writes a new register for each time interval, regardless of how many bolometer data have been received. After making sure all possible data have arrived, write the register.
Mediator should just listen on a socket for connection requests from the receiver data server, and set up to read data as they arrive. When new data shows up, check its serial number and put it into the appropriate register along with the time-matching position information.
The creation and archiving of data frames will have to be keyed to a software timer synchronized with absolute time.
To Do:
- Look through DataNew::seviceMsgQ thoroughly.
- Email John and Clem (cc Ken) about new ideas.
- Continue with KyleWave example.
- Understand Scanner details
- Look at Erik's suggested models, Grabber, Antenna
For Tomorrow:
- Finish looking through serviceMsgQ()
- work on KyleWave example
10/24
How DataNew::serviceMsgQ() works
Wait for data to arrive
Once a message has arrived:
- processTaskMsg
- Loop over boxes:
> read box with NetDataBoard::read(unsigned iBox)
deal with time stuff
- update seq number if necessary
- update time and calculate dTime between current and time last packet arrived
case: data is in current set i.e. seq==currSeq
- note that the box data for that sequence number has arrived, and keep waiting for all boxes
- if all boxes have arrived, call incrimentSampleCount() to buffer the data
case new sequence number i.e. seq > currSeq
if dCurrSeq != 1, log a message. If dCurrSeq > seqJumpThreshold, do not read new data
Usually, dCurrSeq == 1.
Calculate change in seq number and time between most recent packets.
bufferTimeData(iSamp, )
bufferPmacData(iSamp)
Wait for more data to arrive.
10/27
Plan for mce gcp code implimentation: post talk with Ken
MCE:
MCE writes bolometer data to a pipe-file, which is connected to a daemon.
The daemon maintains a TCP connection with the Mediator.
The daemon has a queue which collects data and run files from the MCE into frames. These frames have a fixed time length (tau) which can be synchronized to the Mediator if they both use the same time source.
It sends off a new data frame to the MCE at a fixed time interval tau (~1 second).
These data frames are time-stamped with a sequence number, which corresponds to an absolute time.
Antenna:
The antenna layer collects information such as pointing and weather, and sends it to the Mediator using the existing BICEP antenna data acquisition code.
This means that I need to remove the code in the AntennaRx that polls the boxes, and have it just send everything else at a regular time interval.
Mediator:
The Mediator maintains a queue of data frames, each with a time length tau. The queue length is set to be N frames, (where for BICEP 1 N=3).
Data frames are generated in synch with absolute time.
Data from the MCE arrive on the TCP port and are stored in the appropriate data frame for that time stamp.
Similarly, information from the Antenna layer is stored in the proper time interval for its time stamp.
Every tau seconds, the queue writes the oldest frame to a register, regardless of if it has received information from the MCE and the Antenna layer.
Simultaneously it starts a new frame corresponding to the current time.
What needs to be modified:
MCE -> Need to write a daemon which maintains a TCP connection with the Mediator. It is completely separate from the MCE/MAS, and reads in datafiles and runfiles from a pipe-file, collects them into a fixed time-length data frame, and sends off data frames to the Mediator at a regular time interval. Thus the MCE/MAS code remains completely unchanged.
Antenna-> remove polling of data boxes, and change code to send information at a regular time interval to the Mediator.
Mediator-> Write a dataServer receiver which maintains a TCP connection with the MCE daemon, and reads data frames from that source. This can be modeled after the current grabber interface.
Edit the Mediator message queue to integrate multiple sources of input, similar to SPT.
10/29
Trying to get KyleWave to show up in Viewer page
Look for places where tipper is plugged into higher level things:
AntennaMaster.cc
AntennaMonitor.cc
Tracker.h -> no
Scanner.h
- currently waiting for message.
Think message will come from BicepShare::writeReg()
New BicepShare object defined in:
- AntennaMaster.cc 124
- DataBase.cc 82
AntennaMaster.cc:
- Threads:
1) AntennaControl
2) AntennaRx
3) AntennaDrive
4) AntennaMonitor
5) AntennaSignal
- Relevant classes:
AntennaDrive, AntennaControl, AntennaMonitor, AntennaRx, AntennaData, UmacControl
add pgplot
http://www.dur.ac.uk/physics.astrolab/ppgplot.html changed makefile line 25 to gcc10/31
Trying to run gcp on spudws2
Copy a tar of my current working gcp on bicep0.
Fix all Makefiles to have appropriate directories on spudws2.
Install pgplot.
Can't find proper .h files in pgplot directory.
Abandon.
Sim Mode: attemt #1
Changed viewer.tcl file to start up weather.page. -> works.
Can't type into bicepViewer. ??
what does the command /home/bicep/gcp/bin/bicepAntennaControl do?
look at AntennaControl
analogy in mediator: main program exists in bin_mediator.cc main()
Can't find where the main() for Antenna is, because the one in bin_AntennaMaster.cc does not seem to be the one.