]> jspc29.x-matter.uni-frankfurt.de Git - mimosis_chain.git/commitdiff
finished scurve scans. some stuff, like scan for subsubevents is still missing
authorMaps <maps@ikf>
Thu, 4 Apr 2024 15:55:28 +0000 (17:55 +0200)
committerMaps <maps@ikf>
Thu, 4 Apr 2024 15:55:28 +0000 (17:55 +0200)
cpp/CMakeLists.txt
cpp/main.cxx [deleted file]
cpp/mimosis.cxx
cpp/mimosis.hpp
cpp/scurve-scan.cxx [new file with mode: 0644]
scripts/Mimosis.pm
scripts/cli/mimosis
scripts/pulse/fit-raw.py

index 8ce1275314814b39cf14c48b0ca9dc607727519e..cc0f0057d9796663b36cb2ec6c10d475e6e582c5 100644 (file)
@@ -1,10 +1,24 @@
 cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
 
-project(mimosis-scurves
+project(mimosis
   LANGUAGES C CXX
 )
 
-add_executable(mimosis-scurves main.cxx)
+set(SCURVE_EXE "scurve-scan")
+set(MIMOSIS_LIB "mimosis")
+
+
+add_executable(
+  ${SCURVE_EXE} ${SCURVE_EXE}.cxx
+)
+
+
+add_library(
+  ${MIMOSIS_LIB} SHARED
+  ${MIMOSIS_LIB}.cxx
+)
+
+
 
 if(TRBNETTOOLS_DIR)
   message(${TRBNETTOOLS_DIR})
@@ -12,18 +26,24 @@ else()
   message("TRBNETTOOLS_DIR not provided. Using /d/jspc85/bgutsche/trbnettools")
   set(TRBNETTOOLS_DIR "/d/jspc85/bgutsche/trbnettools")
 endif()
+
 set(TRBNET_LIB_DIR ${TRBNETTOOLS_DIR}/libtrbnet/)
 set(TRBNET_INCLUDE_DIR ${TRBNETTOOLS_DIR}/libtrbnet/)
 
+
+
 if(DABC_DIR)
   message(${DABC_DIR})
 else()
   message("DABC_DIR not provided. Using /d/jspc37/soft/trb3/dabc")
   set(DABC_DIR "/d/jspc37/soft/trb3/dabc")
 endif()
+
 set(DABC_LIB_DIR ${DABC_DIR}/lib/)
 set(DABC_INCLUDE_DIR ${DABC_DIR}/include/)
 
+
+
 include_directories(
   ${TRBNET_INCLUDE_DIR}
   ${DABC_INCLUDE_DIR}
@@ -34,9 +54,15 @@ link_directories(
   ${DABC_LIB_DIR}
 )
 
-target_link_libraries(mimosis-scurves
+
+target_link_libraries(${SCURVE_EXE}
   PRIVATE trbnet
   PRIVATE DabcBase
   PRIVATE DabcHadaq
   PRIVATE DabcMbs
+  PRIVATE ${MIMOSIS_LIB}
+)
+
+target_link_libraries(${MIMOSIS_LIB}
+  PRIVATE trbnet
 )
diff --git a/cpp/main.cxx b/cpp/main.cxx
deleted file mode 100644 (file)
index 1343f40..0000000
+++ /dev/null
@@ -1,556 +0,0 @@
-#include <cstdio>
-#include <cstring>
-#include <csignal>
-#include <unistd.h>
-#include <iostream>
-#include <fstream>
-#include <vector>
-#include <chrono>
-#include <array>
-#include <sys/stat.h>
-
-//Necessary for readout handler
-#include "hadaq/api.h"
-
-//Necessary to control mimosis and trbnet
-#include "trbnet.h"
-
-
-using namespace std::chrono;
-
-//Enum to make access to the information vector more clear
-enum params {STATE, YLOW, YHIG, XLOW, XHIG, REGION, VCASN, VPHFINE};
-
-
-//Collection of data related variables used throughout the programm.
-namespace Data
-{
-    //Main data array holds counts of pulses for every pixel and VPH_FINE
-    std::array<uint32_t,1025*505*256> dataArray;
-
-
-    int dataFraCnt = 0;
-    int limitFra = 500;
-
-    short vphfine;
-
-    //Boundaries within pulses were done
-    int yLow, yHig, xLow, xHig;
-    int yLowMax = 504, yHigMax = 0, xLowMax = 1024, xHigMax = 0;
-    int sLowMax = 255, sHigMax = 0;
-
-    //Directory where data and METADATA will be put.
-    std::string dataDir;
-
-    //Current state of the programm.
-    std::string state;
-
-    //Keep track of VCASN to put in METADATA later.
-    std::vector<std::string> vcasnVec;
-
-    //Measure time of execution of the programm and put
-    //information in METADATA
-    decltype(high_resolution_clock::now()) start;
-
-    //Keep track whether mimosis frame counter was not incremented by 1,
-    //which would indicate droped frames in the R/O.
-    std::vector<uint32_t> mimFraCntNewVec;
-    std::vector<uint32_t> mimFraCntOldVec;
-};
-
-
-
-//Name of PID file.
-const std::string pidName = "/tmp/hldprint-pid";
-
-
-
-//Write PID to PID-file
-void write_pid(void)
-{
-    int pid = (int)getpid();
-
-    FILE *pidFile = fopen(pidName.c_str(), "w");
-
-    if(pidFile == nullptr) {
-       std::printf("ERROR: Couldn't open file.\n");
-       std::exit(-1);
-    }
-
-    fprintf(pidFile, "%d",pid);
-
-    fclose(pidFile);
-}
-
-
-
-//Open a pipe and wait for commands and informations
-//from controller script
-std::vector<std::string> await_params()
-{
-    //Receiving pipe for informations from controller
-    std::string pipeName = "/tmp/scurveipipe";
-
-    FILE *iPipe = fopen(pipeName.c_str(), "r");
-
-    if(iPipe == nullptr) {
-       std::printf("ERROR: Couldn't open file.\n");
-       std::exit(-1);
-    }
-
-
-    //Read from pipe char by char until full frame is reached.
-    //Frames start with START and end with END.
-    //Information is delimited by '-' characters.
-    int buf;
-    bool foundFrame = false, foundSta = false, foundEnd = false;
-    std::string word;
-
-    //Staore all informations, without START and END, in values vector.
-    std::vector<std::string> values;
-
-    buf = fgetc(iPipe);
-
-    while(!foundFrame && buf != EOF)
-    {
-        char c = static_cast<char>(buf);
-
-        if(c == '-') {
-            values.push_back(word);
-            word = "";
-        } else {
-            word += c;
-        }
-
-        if(word == "START") { foundSta = true; }
-        if(word == "END") { foundEnd = true; }
-
-        buf = fgetc(iPipe);
-
-        if(foundSta && foundEnd) {
-            foundFrame = true;
-            break;
-        }
-    }
-
-    //Delete "START" from first position
-    values.erase(values.begin());
-
-    // for (const auto& i: values)
-    //     std::cout << i << '\n';
-
-    fclose(iPipe);
-
-    //Return the whole array.
-    return values;
-}
-
-
-
-//Open a pipe to transmit an acknowledgement to the
-//controller script
-int send_ack()
-{
-    //Transmitting pipe to acknowledge receiving and processing of informations
-    //A simple 'ACK' indicates the controller successful operation
-    std::string pipeName = "/tmp/scurveapipe";
-
-    FILE *iPipe = fopen(pipeName.c_str(), "w");
-
-    if(iPipe == nullptr) {
-       std::printf("ERROR: Couldn't open file.\n");
-       std::exit(-1);
-    }
-
-    std::string msg("ACK");
-    fputs(msg.c_str(),iPipe);
-    fclose(iPipe);
-    return 0;
-}
-
-
-
-//Writing contents of Data::dataArr to file.
-void write_data(std::string reg, std::string vcasn)
-{
-    //For each VCASN a new sub dir is created and a csv file with
-    //the same name holds the data.
-    std::string subDir = Data::dataDir + "/" + reg + "-" + vcasn;
-
-    mkdir(subDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
-
-    std::string fileName = subDir + "/" + reg + "-" + vcasn + ".csv";
-
-
-    //Buffered ofstream increases performance.
-    //One could also dump the whole array as binary file, but this complicates
-    //Post processing a bit.
-    //Another option would be to include root and use TTree's.
-    std::ofstream file(fileName);
-    char buffer[1000000];
-    file.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
-
-    //Only write relevant data between boundaries of scan.
-    for(int y = Data::yLowMax; y <= Data::yHigMax; y++) {
-
-        for(int x = Data::xLowMax; x <= Data::xHigMax; x++) {
-
-            for(int s = Data::sLowMax; s <= Data::sHigMax; s++) {
-
-                uint32_t v = Data::dataArray[(y*1024+x)*255+s];
-                file << v << '\t';
-
-                //Reset data to 0
-                Data::dataArray[(y*1024+x)*255+s] = 0;
-            }
-            file << '\n';
-        }
-    }
-    file.close();
-}
-
-
-
-//Decodeing of mimosis words into pixels
-bool decode_pixel(const uint32_t& word, int& column, int& row, const int& region)
-{
-    const unsigned long pixelcode = (word >> 6) & 0x3ff;
-
-    unsigned long side = 0, topdown = 0;
-
-    if((pixelcode&3) == 0x1 || (pixelcode&3) == 0x2) side = 1;
-    if((pixelcode&3) == 0x3 || (pixelcode&3) == 0x2) topdown = 1;
-
-    row    = (pixelcode>>2)*2 + topdown;
-    column = (((word>>3)&0x7) + region*8)*2 + side;
-
-    return true;
-}
-
-
-
-//Main data taking procedure.
-void take_data(std::string src)
-{
-    hadaq::ReadoutHandle ref = hadaq::ReadoutHandle::Connect(src.c_str());
-    if (ref.null()) return;
-    hadaq::RawEvent *evnt = nullptr;
-
-    bool takeData = false;
-    int region = 0, column, row;
-    short vphfine;
-
-    while (true)
-    {
-        evnt = ref.NextEvent(1.,-1);
-        if (!evnt) continue;
-        hadaq::RawSubevent* sub = nullptr;
-
-        while ((sub = evnt->NextSubevent(sub)) != nullptr)
-        {
-            unsigned headersNow = 0;
-            uint32_t mimFraCntNew = 0;
-            uint32_t mimFraCntOld = 0;
-            bool fraFirst = true;
-            uint32_t pulseMsg = 0;
-            unsigned size = sub->GetNrOfDataWords();
-
-            for( unsigned i = 0; i<size; i++)
-            {
-                uint32_t data = static_cast<uint32_t>(sub->Data(i));
-
-                if((data & 0xFF000000) == 0xFE000000) {
-
-                    headersNow++;
-
-                    if(headersNow == 1) {
-
-                        mimFraCntNew =  (data & 0xFF0000) >> 16;
-                        mimFraCntNew += (data & 0xFF) << 8;
-
-                    } else if(headersNow == 2) {
-
-                        mimFraCntNew +=  data & 0xFF0000;
-                        mimFraCntNew += (data & 0xFF) << 24;
-
-                        if(mimFraCntNew-mimFraCntOld != 1 && !fraFirst) {
-                            Data::mimFraCntNewVec.push_back(mimFraCntNew);
-                            Data::mimFraCntOldVec.push_back(mimFraCntOld);
-                            std::printf("Found skipped mimosis frame counter:\nOld:\t%u\nNew:\t%u\n",mimFraCntOld,mimFraCntNew);
-                        }
-                        mimFraCntOld = mimFraCntNew;
-                        fraFirst = false;
-
-                    } else if(headersNow == 3) {
-
-                        pulseMsg = (data & 0xFF0000) >> 16;
-                        pulseMsg += (data & 0xFF) << 8;
-
-                        // std::printf("%u\t%x\n",size, sub->Data(i));
-
-                    } else if(headersNow == 4) {
-
-                        pulseMsg +=  data & 0xFF0000;
-                        pulseMsg += (data & 0xFF) << 24;
-                        vphfine = ( pulseMsg & 0xFF000000 ) >> 24;
-
-                        // std::printf("%u\t%x\n",size, sub->Data(i));
-                        // std::printf("%x\n", pulseMsg);
-
-                        if( ( ( 0x00c00000 & pulseMsg ) == 0x00c00000 ) &&
-                            (vphfine == Data::vphfine)) {
-
-                            takeData = true;
-                            Data::dataFraCnt++;
-
-                            if(Data::dataFraCnt >= Data::limitFra) {
-                                takeData = false;
-                                Data::dataFraCnt = 0;
-                                goto ENDFUNC;
-                            }
-
-                            Data::sLowMax = vphfine < Data::sLowMax ? vphfine : Data::sLowMax;
-                            Data::sHigMax = vphfine > Data::sHigMax ? vphfine : Data::sHigMax;
-
-                        } else if( ( 0x00c00000 & pulseMsg ) == 0x00400000 ) {
-
-                            takeData = false;
-                            goto ENDFUNC;
-
-                        } else if( ( 0x00c00000 & pulseMsg ) == 0x00000000 ) {
-                            takeData = false;
-                            //Idle
-                        }
-                    }
-
-                } else if((data & 0xFF000000) == 0xFF000000) {
-
-                    headersNow = 0;
-
-                } else {
-
-                    headersNow = 0;
-
-                    if( takeData ) {
-
-                        if( (data & 0xFF000000) == 0xFD000000 ) {
-                            const int tmp =  (data>>16) & 0xFF;
-                            if(tmp > 63) continue;
-                            region = tmp;
-
-                        } else {
-
-                            decode_pixel(data>>16,column,row,region);
-                            if(column >= Data::xLow &&
-                               column <= Data::xHig &&
-                               row >= Data::yLow &&
-                               row < Data::yHig ) {
-                                Data::dataArray[(row*1024+column)*255+vphfine] += 1;
-                                // printf("%d %d %d %d\n",row, column, vphfine, Data::dataArray[(row*1024+column)*255+vphfine]);
-                            }
-                        }
-
-                        if((data & 0x0000FF00) != 0x0000FC00) {
-
-                            decode_pixel(data&0xFFFF,column,row,region);
-
-                            if(column >= Data::xLow &&
-                               column <= Data::xHig &&
-                               row >= Data::yLow &&
-                               row < Data::yHig ) {
-                                Data::dataArray[(row*1024+column)*255+vphfine] += 1;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-    ENDFUNC:
-    ref.Disconnect();
-}
-
-
-
-//Keep track of maximum values of boundaries of scan.
-void find_edge()
-{
-    using namespace Data;
-    yLowMax = yLow < yLowMax ? yLow : yLowMax;
-    yHigMax = yHig > yHigMax ? yHig : yHigMax;
-    xLowMax = xLow < xLowMax ? xLow : xLowMax;
-    xHigMax = xHig > xHigMax ? xHig : xHigMax;
-}
-
-
-
-//Write the METADATA file and put into dataDir.
-void write_meta()
-{
-    std::string fileName = Data::dataDir + "/METADATA";
-
-    std::ofstream file(fileName);
-
-    file << "START:" << '\t' << Data::dataDir << '\n';
-
-    file << "VCASN:";
-    for(const auto& i: Data::vcasnVec) {
-        file << '\t' << i;
-    }
-    file << '\n';
-
-    file << "YMIN:" << '\t' << Data::yLowMax << '\n';
-    file << "YMAX:" << '\t' << Data::yHigMax << '\n';
-    file << "XMIN:" << '\t' << Data::xLowMax << '\n';
-    file << "XMAX:" << '\t' << Data::xHigMax << '\n';
-    file << "SMIN:" << '\t' << Data::sLowMax << '\n';
-    file << "SMAX:" << '\t' << Data::sHigMax << '\n';
-
-    file << "EXITSTATE:" << '\t' << Data::state << '\n';
-
-    auto stop = high_resolution_clock::now();
-    auto duration = duration_cast<seconds>(stop - Data::start);
-    file << "TIME(s):" << '\t' << duration.count() << '\n';
-
-    file << "COMMENT:\t<insert comment here>\n";
-
-    file.close();
-}
-
-
-
-//Signal handler for clean exit at CTRL-C.
-//Data will be dumped and marked with 'INTERRUPTED',
-//if current state was a data taking state.
-void signal_handler( int signum )
-{
-   std::cout << "Interrupt signal (" << signum << ") received Cleaning up...\n";
-
-   if(Data::state == "TAKEDATA" ||
-      Data::state == "WAITDAQ" ||
-      Data::state == "FIT") {
-
-       std::string lastReg = "INTERRUPTED";
-       std::string lastVca = "INTERRUPTED";
-       write_data(lastReg, lastVca);
-       std::cout << "Remining data indicated by INTERRUPTED flags.\n";
-
-   } else {
-   }
-
-   //Remove pid file
-   remove(pidName.c_str());
-
-   write_meta();
-
-   std::exit(signum);
-}
-
-
-
-//main. Make initialization and then enter main loop.
-int main(int argc, char* argv[])
-{
-    //Read stream url
-    std::string src = argv[1];
-
-
-    //Initialize trbnet for this run
-    int trbnetState =  init_ports();
-
-
-    //Start clock to report execution time METADATA
-    Data::start = high_resolution_clock::now();
-
-
-    //Generate the PID file
-    write_pid();
-
-
-    //Register signal SIGINT and signal handler
-    signal(SIGINT, signal_handler);
-
-
-    //Declare stateVec, that will hold the
-    //informations passed from control script
-    std::vector<std::string> stateVec;
-
-
-    //Create main data dir by time stamp
-    std::time_t time = std::time(0);
-    std::tm* now = std::localtime(&time);
-
-    Data::dataDir = std::to_string(now->tm_year + 1900) + '-'
-         + std::to_string(now->tm_mon + 1) + '-'
-         + std::to_string(now->tm_mday) + '-'
-         + std::to_string(now->tm_hour) + '-'
-         + std::to_string(now->tm_min);
-
-    mkdir(Data::dataDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
-
-
-    //Initialize data array with 0's
-    for(int y = 0; y <= 505; y++)
-        for(int x = 0; x <= 1025; x++)
-            for(int s = 0; s <= 256; s++)
-                Data::dataArray[(y*1024+x)*255+s] = 0;
-
-
-    //Main control loop. After init phase,
-    //wait for commands from control script
-    AWAIT:
-    stateVec = await_params();
-    Data::state = stateVec[params::STATE];
-
-    if(Data::state == "TAKEDATA") {
-
-        Data::yLow = std::stoi(stateVec[params::YLOW], nullptr, 10);
-        Data::yHig = Data::yLow + std::stoi(stateVec[params::YHIG], nullptr, 10);
-        Data::xLow = std::stoi(stateVec[params::XLOW], nullptr, 10);
-        Data::xHig = std::stoi(stateVec[params::XHIG], nullptr, 10);
-
-        std::printf("Take data: ");
-        std::printf("%4d %4d %4d %4d\n", Data::yLow, Data::yHig, Data::xLow, Data::xHig);
-        find_edge();
-        send_ack();
-        take_data(src);
-        goto AWAIT;
-
-    } else if(Data::state == "WAITDAQ") {
-
-        // std::printf("At WAITDAQ.\n");
-        send_ack();
-        goto AWAIT;
-
-    } else if(Data::state == "FIT") {
-
-        std::string regStr = stateVec[params::REGION];
-        std::string vcaStr = stateVec[params::VCASN];
-        Data::vcasnVec.push_back(vcaStr);
-        std::printf("Write data: %s %s\n",regStr.c_str(),vcaStr.c_str());
-        write_data(regStr,vcaStr);
-        send_ack();
-        goto AWAIT;
-
-    } else if(Data::state == "DONE") {
-
-        std::printf("Done.\n");
-        send_ack();
-
-        remove(pidName.c_str());
-
-        write_meta();
-
-        return 0;
-
-    } else {
-
-        //Never happend so far, but just in case,
-        //exit cleanly and remove pid file
-        std::printf("Received garbage. Exiting.\n");
-
-        remove(pidName.c_str());
-
-        return 1;
-    }
-}
index c5e434ac1bb3e9f8466a48f074ac42e60d60a4ad..c1d9f2b34a45706ad64cc69f14ec405e1b93afa5 100644 (file)
 #include <iostream>
+#include <vector>
+#include <unistd.h>
+
+#include "mimosis.hpp"
 #include "trbnet.h"
 
-/*  Make sure the right libraries are used, to get trbnet c
- *  code working (from trbnettools use trbnetd/libtrbnet.*).
- *  Also set DAQOPSERVER like usual.
- *  */
 
+#define MIM_I2C_INSTR (0x11<<1)
+#define MIM_I2C_ADD_LSB (0x12<<1)
+#define MIM_I2C_ADD_MSB (0x13<<1)
+#define MIM_I2C_WR (0x14<<1)
+#define MIM_I2C_RD (0x15<<1)
 
-namespace mimosis
-{
+#define TRB_REG_ADDR 0xde01
+#define TRB_REG_READ 0xde04
+#define TRB_OPTION 0
 
-    void register_write(const int& fpga, const int& mim_reg, const int& mim_data, const bool& singleaccess) noexcept
-    {
-        const uint32_t addr = 0x12;
-        const uint32_t cmd  = mim_reg >> 8;
-        const uint32_t data = ((mim_reg & 0xff) << 8 ) + mim_data;
+#define I2C_EXEC 0x1
 
-        if( singleaccess )
-        {
+#define GEN_PAYLOAD_WR(r,d) static_cast<uint32_t>(((r&0xff)<<24)+((d&0xff)<<16)+(r&0xff00)+MIM_I2C_ADD_LSB)
+#define GEN_PAYLOAD_RD(r) static_cast<uint32_t>(((r&0xff)<<16)+(r&0xff00)+MIM_I2C_ADD_LSB)
 
-            {
-                const uint32_t com = (( mim_reg >> 8 ) << 16 ) + ( addr << 1);
-                const uint32_t arr[3] = { 0x010, com, 0x1};
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
+#define GEN_ADD_LSB(r) static_cast<uint32_t>(((r&0xff00)<<8)+MIM_I2C_ADD_LSB)
+#define GEN_ADD_MSB(r) static_cast<uint32_t>(((r&0xff)<<16)+MIM_I2C_ADD_MSB)
+#define GEN_WR(d) static_cast<uint32_t>(((d&0xff)<<16)+MIM_I2C_WR)
 
-            {
-                const uint32_t com = ( mim_reg << 16 ) + ( (addr + 1) << 1);
-                const uint32_t arr[3] = { 0x010, com, 0x1};
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
+#ifndef SLEEPVAL
+#define SLEEPVAL 1000
+#endif
 
-            {
-                const uint32_t com = ( mim_data << 16 ) + ( (addr + 2) << 1);
-                const uint32_t arr[3] = { 0x010, com, 0x1};
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
 
-        }
-        else if ( !singleaccess )
+
+
+void mimosis::register_write(
+    const uint16_t& fpga,
+    const uint16_t& mim_reg,
+    const uint16_t& mim_data,
+    const bool& singleAccess
+) noexcept {
+
+    if( singleAccess ) {
+
+        std::vector<uint32_t> payload = {
+        GEN_ADD_LSB(mim_reg),
+        GEN_ADD_MSB(mim_reg),
+        GEN_WR(mim_data) };
+
+        for (auto i: payload)
         {
-            const uint32_t com = ( data << 16 ) + ( cmd << 8 ) + ( addr << 1);
-            const uint32_t arr[3] = { 0x001, com, 0x1};
-            trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
+            const uint32_t arr[3] = { 0x010, i, I2C_EXEC};
+            trb_register_write_mem(fpga, TRB_REG_ADDR, TRB_OPTION, arr, 3);
+            usleep(SLEEPVAL);
         }
+
+    } else if ( !singleAccess ) {
+
+        const uint32_t arr[3] = { 0x001, GEN_PAYLOAD_WR(mim_reg,mim_data), I2C_EXEC };
+
+        trb_register_write_mem( fpga, TRB_REG_ADDR, TRB_OPTION, arr, 3);
+        usleep(SLEEPVAL);
     }
+}
 
 
-    int register_read(const int& fpga, const int& mim_reg, const bool& singleaccess) noexcept
-    {
-        const uint32_t addr = 0x12;
-        const uint32_t cmd  = mim_reg >> 8;
-        const uint32_t data = mim_reg & 0xff;
 
-        if( singleaccess )
+int mimosis::register_read(const int& fpga, const int& mim_reg, const bool& singleAccess) noexcept
+{
+    if( singleAccess ) {
+
+        std::vector<uint32_t> payload = {
+        GEN_ADD_LSB(mim_reg),
+        GEN_ADD_MSB(mim_reg)};
+
+        for (auto i: payload)
         {
-            return 0;
+            const uint32_t arr[3] = { 0x010, i, I2C_EXEC};
+            trb_register_write_mem(fpga, TRB_REG_ADDR, TRB_OPTION, arr, 3);
+            usleep(SLEEPVAL);
         }
-        else if( !singleaccess )
+
+    } else if( !singleAccess ) {
+
         {
-            {
-                const uint32_t com = ( data << 16 ) + ( cmd << 8 ) + ( addr << 1);
-                const uint32_t arr[3] = { 0x0, com, 0x1 };
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
-
-            {
-                const uint32_t com = ( 0x15 << 1);
-                const uint32_t arr[3] = { 0x110, com, 0x1 };
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
-
-            const uint32_t size = 2;
-            uint32_t res[size];
-            trb_register_read(fpga, 0xde04, res, size);
-            return res[1];
+            const uint32_t arr[3] = { 0x0, GEN_PAYLOAD_RD(mim_reg), I2C_EXEC };
+            trb_register_write_mem(fpga, TRB_REG_ADDR, 0, arr, 3);
+        }
+
+        usleep(SLEEPVAL);
+
+        {
+            const uint32_t arr[3] = { 0x110, MIM_I2C_RD, I2C_EXEC };
+            trb_register_write_mem(fpga, TRB_REG_ADDR, 0, arr, 3);
         }
-        return 0;
-    }
 
+        usleep(SLEEPVAL);
 
-    void instr_write(const int& fpga, const int& cmd) noexcept
-    {
-        const uint32_t com = ( cmd << 8 ) + ( 0x11 << 1 );
-        const uint32_t arr[3] = { 0x0, com, 0x1 };
-        trb_register_write_mem(fpga, 0xde01, 0, arr, 3 );
+       const int size = 2;
+       uint32_t res[size];
+       trb_register_read(fpga, TRB_REG_READ, res, size);
+
+        return res[1] & 0x00ff;
     }
 
-};
+    usleep(SLEEPVAL);
+
+    return -1;
+}
 
 
-namespace adc
+
+void mimosis::instr_write(const int& fpga, const int& cmd) noexcept
 {
+    const uint32_t com = (cmd<<8) + MIM_I2C_INSTR;
+    const uint32_t arr[3] = { 0x0, com, 0x1 };
+    trb_register_write_mem(fpga, TRB_REG_ADDR, 0, arr, 3 );
+    usleep(SLEEPVAL);
+}
 
-    void write(const int& fpga, const int& addr, const int& cmd, const int& data) noexcept
-    {
-        const uint32_t com = (data << 16) + (cmd << 8) + 0x80 + addr;
-        const uint32_t arr[2] = { 0x001, com };
-        trb_register_write_mem(fpga, 0xd681, 0, arr, 2 );
-    }
 
 
-    int read(const int& fpga, const int& addr, const int& cmd) noexcept
-    {
-        const uint32_t com = (cmd << 8) + 0x80 + addr;
-        const uint32_t arr[2] = { 0x101, com };
-        trb_register_write_mem(fpga, 0xd681, 0, arr, 2 );
+void adc::write(const int& fpga, const int& addr, const int& cmd, const int& data) noexcept
+{
+    const uint32_t com = (data << 16) + (cmd << 8) + 0x80 + addr;
+    const uint32_t arr[2] = { 0x001, com };
+    trb_register_write_mem(fpga, 0xd681, 0, arr, 2 );
+}
 
-        uint32_t res[2];
-        trb_register_read(fpga, 0xd684, res, 2);
 
-        return res[1];
-    }
 
-};
+int adc::read(const int& fpga, const int& addr, const int& cmd) noexcept
+{
+    const uint32_t com = (cmd << 8) + 0x80 + addr;
+    const uint32_t arr[2] = { 0x101, com };
+    trb_register_write_mem(fpga, 0xd681, 0, arr, 2 );
+
+    uint32_t res[2];
+    trb_register_read(fpga, 0xd684, res, 2);
+
+    return res[1] & 0x00ff;
+}
index c5e434ac1bb3e9f8466a48f074ac42e60d60a4ad..62397dc17966cf4648689150ae39ab12cce2df96 100644 (file)
-#include <iostream>
-#include "trbnet.h"
-
-/*  Make sure the right libraries are used, to get trbnet c
- *  code working (from trbnettools use trbnetd/libtrbnet.*).
- *  Also set DAQOPSERVER like usual.
- *  */
+#ifndef MIMOSIS_HPP
+#define MIMOSIS_HPP
 
 
 namespace mimosis
 {
+    void register_write(const uint16_t& fpga, const uint16_t& mim_reg, const uint16_t& mim_data, const bool& singleaccess) noexcept;
 
-    void register_write(const int& fpga, const int& mim_reg, const int& mim_data, const bool& singleaccess) noexcept
-    {
-        const uint32_t addr = 0x12;
-        const uint32_t cmd  = mim_reg >> 8;
-        const uint32_t data = ((mim_reg & 0xff) << 8 ) + mim_data;
-
-        if( singleaccess )
-        {
-
-            {
-                const uint32_t com = (( mim_reg >> 8 ) << 16 ) + ( addr << 1);
-                const uint32_t arr[3] = { 0x010, com, 0x1};
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
-
-            {
-                const uint32_t com = ( mim_reg << 16 ) + ( (addr + 1) << 1);
-                const uint32_t arr[3] = { 0x010, com, 0x1};
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
-
-            {
-                const uint32_t com = ( mim_data << 16 ) + ( (addr + 2) << 1);
-                const uint32_t arr[3] = { 0x010, com, 0x1};
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
-
-        }
-        else if ( !singleaccess )
-        {
-            const uint32_t com = ( data << 16 ) + ( cmd << 8 ) + ( addr << 1);
-            const uint32_t arr[3] = { 0x001, com, 0x1};
-            trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-        }
-    }
-
-
-    int register_read(const int& fpga, const int& mim_reg, const bool& singleaccess) noexcept
-    {
-        const uint32_t addr = 0x12;
-        const uint32_t cmd  = mim_reg >> 8;
-        const uint32_t data = mim_reg & 0xff;
-
-        if( singleaccess )
-        {
-            return 0;
-        }
-        else if( !singleaccess )
-        {
-            {
-                const uint32_t com = ( data << 16 ) + ( cmd << 8 ) + ( addr << 1);
-                const uint32_t arr[3] = { 0x0, com, 0x1 };
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
-
-            {
-                const uint32_t com = ( 0x15 << 1);
-                const uint32_t arr[3] = { 0x110, com, 0x1 };
-                trb_register_write_mem(fpga, 0xde01, 0, arr, 3);
-            }
-
-            const uint32_t size = 2;
-            uint32_t res[size];
-            trb_register_read(fpga, 0xde04, res, size);
-            return res[1];
-        }
-        return 0;
-    }
-
-
-    void instr_write(const int& fpga, const int& cmd) noexcept
-    {
-        const uint32_t com = ( cmd << 8 ) + ( 0x11 << 1 );
-        const uint32_t arr[3] = { 0x0, com, 0x1 };
-        trb_register_write_mem(fpga, 0xde01, 0, arr, 3 );
-    }
+    int register_read(const int& fpga, const int& mim_reg, const bool& singleaccess) noexcept;
 
+    void instr_write(const int& fpga, const int& cmd) noexcept;
 };
 
 
+
 namespace adc
 {
+    void write(const int& fpga, const int& addr, const int& cmd, const int& data) noexcept;
 
-    void write(const int& fpga, const int& addr, const int& cmd, const int& data) noexcept
-    {
-        const uint32_t com = (data << 16) + (cmd << 8) + 0x80 + addr;
-        const uint32_t arr[2] = { 0x001, com };
-        trb_register_write_mem(fpga, 0xd681, 0, arr, 2 );
-    }
-
-
-    int read(const int& fpga, const int& addr, const int& cmd) noexcept
-    {
-        const uint32_t com = (cmd << 8) + 0x80 + addr;
-        const uint32_t arr[2] = { 0x101, com };
-        trb_register_write_mem(fpga, 0xd681, 0, arr, 2 );
-
-        uint32_t res[2];
-        trb_register_read(fpga, 0xd684, res, 2);
-
-        return res[1];
-    }
-
+    int read(const int& fpga, const int& addr, const int& cmd) noexcept;
 };
+
+#endif //MIMOSIS_HPP
diff --git a/cpp/scurve-scan.cxx b/cpp/scurve-scan.cxx
new file mode 100644 (file)
index 0000000..824dc99
--- /dev/null
@@ -0,0 +1,843 @@
+#include <cstdio>
+#include <cstring>
+#include <csignal>
+#include <unistd.h>
+#include <stdio.h>
+#include <math.h>
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <chrono>
+#include <array>
+#include <sys/stat.h>
+
+//Necessary for readout handler
+#include "hadaq/api.h"
+
+//Necessary to control mimosis and trbnet
+#include "trbnet.h"
+
+//Necessary for mimosis specific functions
+#include "mimosis.hpp"
+
+#define FPGA 0xa000
+
+#define VPHFINE 0x0046
+
+#define SUPERINDEX(x,y,s) ((y*1024+x)*256+s)
+
+using namespace std::chrono;
+
+//Enum to make access to the information vector more clear
+enum params {
+    STATE,
+    YSTA,
+    YEND,
+    YTRA,
+    XLOW,
+    XHIG,
+    VPHSTA,
+    VPHEND,
+    VPHSTEP,
+    COUNTS,
+    MOD,
+    REGION,
+    VCASN,
+    SINGLEACCESS
+};
+
+
+//Collection of data related variables used throughout the programm.
+namespace Data
+{
+    std::string source;
+    //Main data array holds counts of pulses for every pixel and VPH_FINE
+    std::array<unsigned,1024*504*256> dataArray;
+
+    //Current state of the programm.
+    std::string state;
+
+    //Boundaries within pulses were done
+    int yLowMax = 503, yHigMax = 0, xLowMax = 1023, xHigMax = 0;
+
+    //Directory where data and METADATA will be put.
+    std::string dataDir;
+
+    //Keep track of VCASN to put in METADATA later.
+    std::vector<std::string> vcasnVec;
+
+    bool singleAccess = true;
+    //Measure time of execution of the programm and put
+    //information in METADATA
+    decltype(high_resolution_clock::now()) start;
+};
+
+
+
+namespace Stats
+{
+    int totalFrames = 0;
+    int totalFramesSkipped = 0;
+};
+
+
+//Name of PID file.
+const std::string pidName = "/tmp/hldprint-pid";
+
+
+
+void mimosis_sec_write(uint16_t fpga, uint16_t reg, uint16_t data, bool sa)
+{
+    uint16_t readVal = mimosis::register_read( fpga, reg, sa);
+
+    int cnt = 0;
+
+    while (readVal!= data)
+    {
+        mimosis::register_write( fpga, reg, data, sa );
+        readVal = mimosis::register_read( fpga, reg, sa );
+
+        cnt++;
+
+        if(cnt >= 1000)
+        {
+            std::printf("Cannot write 0x%04x to 0x%04x.\nExiting.\n",data, reg);
+            std::exit(-1);
+            break;
+        }
+    }
+}
+
+
+
+//Write PID to PID-file
+void write_pid(void)
+{
+    int pid = (int)getpid();
+
+    FILE *pidFile = fopen(pidName.c_str(), "w");
+
+    if(pidFile == nullptr) {
+       std::printf("ERROR: Couldn't open file.\n");
+       std::exit(-1);
+    }
+
+    fprintf(pidFile, "%d",pid);
+
+    fclose(pidFile);
+}
+
+
+
+//Open a pipe and wait for commands and informations
+//from controller script
+std::vector<std::string> await_params()
+{
+    //Receiving pipe for informations from controller
+    std::string pipeName = "/tmp/scurveipipe";
+
+    FILE *iPipe = fopen(pipeName.c_str(), "r");
+
+    if(iPipe == nullptr) {
+       std::printf("ERROR: Couldn't open file.\n");
+       std::exit(-1);
+    }
+
+
+    //Read from pipe char by char until full frame is reached.
+    //Frames start with START and end with END.
+    //Information is delimited by '-' characters.
+    int buf;
+    bool foundFrame = false, foundSta = false, foundEnd = false;
+    std::string word;
+
+    //Staore all informations, without START and END, in values vector.
+    std::vector<std::string> values;
+
+    buf = fgetc(iPipe);
+
+    while(!foundFrame && buf != EOF)
+    {
+        char c = static_cast<char>(buf);
+
+        if(c == '-') {
+            values.push_back(word);
+            word = "";
+        } else {
+            word += c;
+        }
+
+        if(word == "START") { foundSta = true; }
+        if(word == "END") { foundEnd = true; }
+
+        buf = fgetc(iPipe);
+
+        if(foundSta && foundEnd) {
+            foundFrame = true;
+            break;
+        }
+    }
+
+    //Delete "START" from first position
+    values.erase(values.begin());
+
+    // for (const auto& i: values)
+    //     std::cout << i << '\n';
+
+    fclose(iPipe);
+
+    //Return the whole array.
+    return values;
+}
+
+
+
+//Open a pipe to transmit an acknowledgement to the
+//controller script
+int send_ack()
+{
+    //Transmitting pipe to acknowledge receiving and processing of informations
+    //A simple 'ACK' indicates the controller successful operation
+    std::string pipeName = "/tmp/scurveapipe";
+
+    FILE *iPipe = fopen(pipeName.c_str(), "w");
+
+    if(iPipe == nullptr) {
+       std::printf("ERROR: Couldn't open file.\n");
+       std::exit(-1);
+    }
+
+    std::string msg("ACK");
+    fputs(msg.c_str(),iPipe);
+    fclose(iPipe);
+    return 0;
+}
+
+
+
+//Writing contents of Data::dataArr to file.
+void write_data(std::string reg, std::string vcasn)
+{
+    //For each VCASN a new sub dir is created and a csv file with
+    //the same name holds the data.
+    std::string subDir = Data::dataDir + "/" + reg + "-" + vcasn;
+
+    mkdir(subDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+
+    std::string fileName = subDir + "/" + reg + "-" + vcasn + ".csv";
+
+    //Buffered ofstream increases performance.
+    //One could also dump the whole array as binary file, but this complicates
+    //Post processing a bit.
+    //Another option would be to include root and use TTree's.
+    std::ofstream file(fileName);
+    char buffer[1000000];
+    file.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
+
+    // std::printf("%d %d %d %d\n", Data::yLowMax, Data::yHigMax, Data::xLowMax, Data::xHigMax);
+
+    //Only write relevant data between boundaries of scan.
+    for(int y = Data::yLowMax; y <= Data::yHigMax; y++) {
+
+        for(int x = Data::xLowMax; x <= Data::xHigMax; x++) {
+
+            for(int s = 0; s <= 255; s++) {
+
+                auto v = Data::dataArray[SUPERINDEX(x,y,s)];
+
+                file << v << '\t';
+                // file << s << '\t';
+
+                //Reset data to 0
+                Data::dataArray[SUPERINDEX(x,y,s)] = 0;
+            }
+            file << '\n';
+        }
+    }
+    file.close();
+}
+
+
+
+//Decodeing of mimosis words into pixels
+void decode_pixel(const uint32_t& word, unsigned int& column, unsigned int& row, unsigned int& region)
+{
+    unsigned int pixelcode = (word >> 6) & 0x3ff;
+
+    unsigned int side = 0, topdown = 0;
+
+    if((pixelcode&3) == 0x1 || (pixelcode&3) == 0x2) side = 1;
+    if((pixelcode&3) == 0x3 || (pixelcode&3) == 0x2) topdown = 1;
+
+    row    = (pixelcode>>2)*2 + topdown;
+    column = (((word>>3)&0x7) + region*8)*2 + side;
+}
+
+
+
+//Main data taking procedure.
+void loop_vph(
+    int yLow, int yHig,
+    int xLow, int xHig,
+    int vphSta, int vphEnd, int vphTra,
+    int maxCounts, int mod, int exp)
+{
+#ifdef DEBUG
+    std::printf("loop_vph(): yLow(%4d) yHig(%4d) xLow(%4d) xHig(%4d) vphSta(%4d) vphEnd(%4d) vphTra(%4d) maxCounts(%4d) mod(%8d)\n",
+                yLow,yHig,xLow,xHig,vphSta,vphEnd,vphTra,maxCounts,mod);
+#endif
+
+    int pulse = static_cast<int>(std::pow(2.0,static_cast<double>(exp)));
+
+    hadaq::ReadoutHandle ref = hadaq::ReadoutHandle::Connect(Data::source.c_str());
+    if (ref.null()) return;
+    hadaq::RawEvent *evnt = nullptr;
+
+    for(int vphfine = vphSta;
+        vphfine <= vphEnd;
+        vphfine += vphTra)
+    // for(int vphfine = vphSta;
+    //     vphfine <= vphEnd;
+    //     vphfine++)
+    {
+        std::printf("Scan: %3d\r",vphfine);
+        fflush(stdout);
+
+        //Set VPH_FINE
+        mimosis_sec_write( FPGA, VPHFINE, vphfine, Data::singleAccess );
+
+        auto start = high_resolution_clock::now();
+        auto stop = high_resolution_clock::now();
+        auto duration = duration_cast<microseconds>(stop-start);
+
+        for(int mimTra = 0;
+            mimTra<maxCounts;
+            mimTra++)
+        {
+            evnt = ref.NextEvent(1.,-1);
+            if (!evnt) continue;
+
+            hadaq::RawSubevent* sub = nullptr;
+
+            while ((sub = evnt->NextSubevent(sub)) != nullptr)
+            {
+                unsigned size = sub->GetNrOfDataWords();
+
+                int headerNow = 0;
+
+                uint32_t mimFraCnt;
+
+                unsigned region = 0, column = 0, row = 0;
+
+                for( unsigned i = 0; i<size; i++)
+                {
+                    uint32_t data = static_cast<uint32_t>(sub->Data(i));
+
+                    if((data & 0xFF000000) == 0xFE000000) {
+
+                        ++headerNow;
+
+                        if(headerNow == 1) {
+
+                            mimFraCnt  = (data & 0xFF0000) >> 16;
+                            mimFraCnt += (data & 0xFF) << 8;
+
+                        } else if(headerNow == 2) {
+
+                            mimFraCnt += data & 0xFF0000;
+                            mimFraCnt += (data & 0xFF) << 24;
+
+                        } else if(headerNow == 3) {
+                        } else if(headerNow == 4) {
+                        }
+
+                    } else if((data & 0xFF000000) == 0xFF000000) {
+
+                        headerNow = 0;
+                        mimTra++;
+
+                    } else {
+
+                        if( (data & 0xFF000000) == 0xFD000000 ) {
+
+                            int tmp =  (data>>16) & 0xFF;
+                            if(tmp > 63) continue;
+                            region = tmp;
+
+                        } else {
+
+                            decode_pixel(data>>16,column,row,region);
+
+                            if(column >= xLow &&
+                               column <= xHig &&
+                               row >= yLow &&
+                               row < yHig &&
+                               mimFraCnt%pulse == mod) {
+
+                                // if (vphfine%vphTra == 0)
+                                Data::dataArray[SUPERINDEX(column,row,vphfine)] += 1;
+                            }
+                        }
+
+                        if((data & 0x0000FF00) != 0x0000FC00) {
+
+                            decode_pixel(data&0xFFFF,column,row,region);
+
+                            if(column >= xLow &&
+                               column <= xHig &&
+                               row >= yLow &&
+                               row < yHig &&
+                               mimFraCnt%pulse == mod) {
+
+                                // if (vphfine%vphTra == 0)
+                                Data::dataArray[SUPERINDEX(column,row,vphfine)] += 1;
+                            }
+                        }
+                    }
+
+                    if(mimTra >= maxCounts) {
+                        goto MAXCOUNTS;
+                    }
+
+                } // End loop over data in sub event
+            } // End loop over sub-events in event
+        } //End while duration
+        MAXCOUNTS:
+        ;
+    }
+    std::printf("\n");
+    ref.Disconnect();
+}
+
+
+
+int find_mod(
+    int yLow, int yHig,
+    int xLow, int xHig,
+    int modPulse)
+{
+    int pulse = static_cast<int>(std::pow(2.0,static_cast<double>(modPulse)));
+
+    int modFound = -1;
+
+    const int modN = 2;
+    std::vector<int> modVec(modN);
+    for(auto& i: modVec) { i = -1; }
+    int modInd = 0;
+    int modX = -1,modY = -1;
+
+    //Set VPH_FINE to smth high, so pulses get visible
+    mimosis_sec_write( FPGA, VPHFINE, 0xff, Data::singleAccess );
+
+    hadaq::ReadoutHandle ref = hadaq::ReadoutHandle::Connect(Data::source.c_str());
+    if (ref.null()) return -2;
+    hadaq::RawEvent *evnt = nullptr;
+
+    uint32_t lastMimFraCnt;
+
+    while(modFound == -1)
+    {
+        while(true)
+        {
+            evnt = ref.NextEvent(1.,-1);
+            if (!evnt) continue;
+
+            hadaq::RawSubevent* sub = nullptr;
+
+            while ((sub = evnt->NextSubevent(sub)) != nullptr)
+            {
+                unsigned size = sub->GetNrOfDataWords();
+                int headerNow = 0;
+                uint32_t mimFraCnt;
+                unsigned region = 0, column = 0, row = 0;
+
+                for( unsigned i = 0; i<size; i++)
+                {
+                    uint32_t data = static_cast<uint32_t>(sub->Data(i));
+
+                    if((data & 0xFF000000) == 0xFE000000) {
+
+                        ++headerNow;
+
+                        if(headerNow == 1) {
+
+                            mimFraCnt  = (data & 0xFF0000) >> 16;
+                            mimFraCnt += (data & 0xFF) << 8;
+
+                        } else if(headerNow == 2) {
+
+                            mimFraCnt += data & 0xFF0000;
+                            mimFraCnt += (data & 0xFF) << 24;
+
+                        } else if(headerNow == 3) {
+                        } else if(headerNow == 4) {
+                        }
+
+                    } else if((data & 0xFF000000) == 0xFF000000) {
+
+                        headerNow = 0;
+
+                    } else {
+
+                        if( (data & 0xFF000000) == 0xFD000000 ) {
+
+                            int tmp =  (data>>16) & 0xFF;
+                            if(tmp > 63) continue;
+                            region = tmp;
+
+                        } else {
+
+                            decode_pixel(data>>16,column,row,region);
+
+                            if(column >= xLow &&
+                               column <= xHig &&
+                               row >= yLow &&
+                               row < yHig &&
+                               lastMimFraCnt != mimFraCnt &&
+                               modInd < modN &&
+                               (row == modY || modY == -1) &&
+                               (column == modX || modX == -1)) {
+
+                                modY = row;
+                                modX = column;
+
+                                modVec[modInd] = mimFraCnt%pulse;
+
+                                modInd++;
+
+                                lastMimFraCnt = mimFraCnt;
+
+                                if(modInd == modN) { goto EVALMODS; }
+                            }
+                        }
+
+                        if((data & 0x0000FF00) != 0x0000FC00) {
+
+                            decode_pixel(data&0xFFFF,column,row,region);
+
+                            if(column >= xLow &&
+                               column <= xHig &&
+                               row >= yLow &&
+                               row < yHig &&
+                               lastMimFraCnt != mimFraCnt &&
+                               modInd < modN &&
+                               (row == modY || modY == -1) &&
+                               (column == modX || modX == -1)) {
+
+                                modY = row;
+                                modX = column;
+
+                                modVec[modInd] = mimFraCnt%pulse;
+
+                                modInd++;
+
+                                lastMimFraCnt = mimFraCnt;
+
+                                if(modInd == modN) { goto EVALMODS; }
+                            }
+                        }
+                    }
+                } // End loop over data in sub event
+            } // End loop over sub-events in event
+        }
+
+        EVALMODS:
+
+        int firstMod = modVec[0];
+        int wrongMods = 0;
+
+        for(int i = 1; i < modN; i++) {
+            if(modVec[i] != firstMod) {
+                wrongMods++;
+            }
+        }
+
+        if(wrongMods > 0) {
+            modInd = 0;
+            continue;
+        } else if(wrongMods == 0) {
+            modFound = firstMod;
+            break;
+        }
+    } //End while mod not found
+
+    ref.Disconnect();
+    return modFound;
+}
+
+
+
+void loop_rows(
+    int ySta, int yEnd, int yTra,
+    int xSta, int xEnd,
+    int vphSta, int vphEnd, int vphTra,
+    int maxCounts, int exp)
+{
+#ifdef DEBUG
+    std::printf("loop_rows(): ySta(%4d) yEnd(%4d) yTra(%4d) xSta(%4d) xEnd(%4d) vphSta(%4d) vphEnd(%4d) vphTra(%4d) maxCounts(%8d) exp(%4d)\n",
+                ySta,yEnd,yTra,xSta,xEnd,vphSta,vphEnd,vphTra,maxCounts,exp);
+#endif
+
+    for(int yOff = ySta;
+        yOff <= yEnd;
+        yOff += yTra)
+    {
+        std::printf("Mark pixels: %d - %d, %d - %d\n", yOff, yOff+yTra-1, xSta, xEnd);
+
+        int y = yOff;
+
+        //Mark pixels for pulsing
+        for(; y < yOff + yTra && y <= yEnd; y++)
+        {
+            Data::yLowMax = y < Data::yLowMax ? y : Data::yLowMax;
+            Data::yHigMax = y > Data::yHigMax ? y : Data::yHigMax;
+
+            int regAddY = y/8;
+            int regBitY = (1<<(y%8));
+            int regWordY = (regAddY<<8)+0x84;
+
+            mimosis_sec_write(FPGA, regWordY, regBitY, Data::singleAccess );
+
+            int regAddX;
+            int regBitX;
+
+            int currRegX = xSta/16;
+
+            int word82 = 0;
+            int word81 = 0;
+
+            for (int x = xSta; x <= xEnd; x++)
+            {
+                Data::xLowMax = x < Data::xLowMax ? x : Data::xLowMax;
+                Data::xHigMax = x > Data::xHigMax ? x : Data::xHigMax;
+
+                if((x/16) == currRegX &&
+                    x != xEnd) {
+
+                    if      (x%2 == 1) { word82 |= (1<<((x/2)%8)); }
+                    else if (x%2 == 0) { word81 |= (1<<((x/2)%8)); }
+
+                } else {
+
+                    if(word82 == word81) {
+
+                        int addr = (currRegX<<8) + 0x83;
+                        mimosis_sec_write( FPGA, addr, word81, Data::singleAccess );
+                        mimosis::instr_write( FPGA,  0x05 );
+                        mimosis_sec_write( FPGA, addr, 0, Data::singleAccess );
+
+                    } else {
+                        int addr81 = (currRegX<<8) + 0x81;
+                        int addr82 = (currRegX<<8) + 0x82;
+                        mimosis_sec_write( FPGA, addr81, word81, Data::singleAccess );
+                        mimosis_sec_write( FPGA, addr82, word82, Data::singleAccess );
+                        mimosis::instr_write( FPGA,  0x05 );
+                        mimosis_sec_write( FPGA, addr81, 0, Data::singleAccess );
+                        mimosis_sec_write( FPGA, addr82, 0, Data::singleAccess );
+                    }
+                    currRegX = x/16;
+
+                    word81 = 0;
+                    word82 = 0;
+
+                    if      (x%2 == 1) { word82 = (1<<((x/2)%8)); }
+                    else if (x%2 == 0) { word81 = (1<<((x/2)%8)); }
+                }
+            }
+            mimosis_sec_write(FPGA, regWordY, 0x0, Data::singleAccess );
+        }
+
+        int mod = find_mod(yOff, y, xSta, xEnd, exp);
+
+        mimosis_sec_write( FPGA, VPHFINE, 0, Data::singleAccess );
+        sleep(1);
+
+        loop_vph(yOff, y, xSta, xEnd, vphSta, vphEnd, vphTra, maxCounts, mod, exp);
+
+        mimosis::instr_write( FPGA, 0x3f );
+        mimosis::instr_write( FPGA, 0x04 );
+        mimosis::instr_write( FPGA, 0x3e );
+
+        //Set VPH_FINE back to zero, to get rid of peak at begining of scan
+        //Do it double, to be sure
+        mimosis_sec_write( FPGA, VPHFINE, 0, Data::singleAccess );
+    }
+}
+
+
+
+//Write the METADATA file and put into dataDir.
+void write_meta()
+{
+    std::string fileName = Data::dataDir + "/METADATA";
+
+    std::ofstream file(fileName);
+
+    file << "START:" << '\t' << Data::dataDir << '\n';
+
+    file << "VCASN:";
+    for(const auto& i: Data::vcasnVec) {
+        file << '\t' << i;
+    }
+    file << '\n';
+
+    file << "YMIN:" << '\t' << Data::yLowMax << '\n';
+    file << "YMAX:" << '\t' << Data::yHigMax << '\n';
+    file << "XMIN:" << '\t' << Data::xLowMax << '\n';
+    file << "XMAX:" << '\t' << Data::xHigMax << '\n';
+
+    file << "EXITSTATE:" << '\t' << Data::state << '\n';
+
+    auto stop = high_resolution_clock::now();
+    auto duration = duration_cast<seconds>(stop - Data::start);
+    file << "TIME(s):" << '\t' << duration.count() << '\n';
+
+    file << "COMMENT:\t<insert comment here>\n";
+
+    file.close();
+}
+
+
+
+//Signal handler for clean exit at CTRL-C.
+//Data will be dumped and marked with 'INTERRUPTED',
+//if current state was a data taking state.
+void signal_handler( int signum )
+{
+   std::cout << "Interrupt signal (" << signum << ") received Cleaning up...\n";
+
+   if(Data::state == "TAKEDATA" ||
+      Data::state == "WAITDAQ" ||
+      Data::state == "FIT") {
+
+       std::string lastReg = "INTERRUPTED";
+       std::string lastVca = "INTERRUPTED";
+       write_data(lastReg, lastVca);
+       std::cout << "Remining data indicated by INTERRUPTED flags.\n";
+
+   } else {
+   }
+
+    //Set VPH_FINE back to zero, to get rid of peak at begining of scan
+    //Do it double, to be sure
+    mimosis_sec_write( FPGA, VPHFINE, 0, Data::singleAccess );
+
+   //Remove pid file
+   remove(pidName.c_str());
+
+   write_meta();
+
+   std::exit(signum);
+}
+
+
+
+//main. Make initialization and then enter main loop.
+int main(int argc, char* argv[])
+{
+    //Read stream url
+    Data::source = argv[1];
+
+
+    //Initialize trbnet for this run
+    int trbnetState =  init_ports();
+
+
+    //Start clock to report execution time METADATA
+    Data::start = high_resolution_clock::now();
+
+
+    //Generate the PID file
+    write_pid();
+
+
+    //Register signal SIGINT and signal handler
+    signal(SIGINT, signal_handler);
+
+
+    //Declare stateVec, that will hold the
+    //informations passed from control script
+    std::vector<std::string> stateVec;
+
+
+    //Create main data dir by time stamp
+    std::time_t time = std::time(0);
+    std::tm* now = std::localtime(&time);
+
+    Data::dataDir = std::to_string(now->tm_year + 1900) + '-'
+         + std::to_string(now->tm_mon + 1) + '-'
+         + std::to_string(now->tm_mday) + '-'
+         + std::to_string(now->tm_hour) + '-'
+         + std::to_string(now->tm_min);
+
+    mkdir(Data::dataDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+
+
+    //Initialize data array with 0's
+    for(int y = 0; y < 504; y++)
+        for(int x = 0; x < 1024; x++)
+            for(int s = 0; s < 256; s++)
+                Data::dataArray[SUPERINDEX(x,y,s)] = 0;
+
+
+    //Main control loop. After init phase,
+    //wait for commands from control script
+    AWAIT:
+    stateVec = await_params();
+    Data::state = stateVec[STATE];
+    Data::singleAccess = stateVec[SINGLEACCESS] == "1";
+
+    if(Data::state == "TAKEDATA") {
+
+        loop_rows(
+            std::stoi(stateVec[YSTA], nullptr, 10),
+            std::stoi(stateVec[YEND], nullptr, 10),
+            std::stoi(stateVec[YTRA], nullptr, 10),
+            std::stoi(stateVec[XLOW], nullptr, 10),
+            std::stoi(stateVec[XHIG], nullptr, 10),
+            std::stoi(stateVec[VPHSTA], nullptr, 10),
+            std::stoi(stateVec[VPHEND], nullptr, 10),
+            std::stoi(stateVec[VPHSTEP], nullptr, 10),
+            std::stoi(stateVec[COUNTS], nullptr, 10),
+            std::stoi(stateVec[MOD], nullptr, 10)
+        );
+
+        send_ack();
+
+        goto AWAIT;
+
+    } else if(Data::state == "FIT") {
+
+        std::string regStr = stateVec[REGION];
+        std::string vcaStr = stateVec[VCASN];
+
+        Data::vcasnVec.push_back(vcaStr);
+        std::printf("Write data: %s %s\n",regStr.c_str(),vcaStr.c_str());
+
+        write_data(regStr,vcaStr);
+        send_ack();
+
+        goto AWAIT;
+
+    } else if(Data::state == "DONE") {
+
+        std::printf("Done.\n");
+        send_ack();
+
+        remove(pidName.c_str());
+
+        write_meta();
+
+        return 0;
+
+    } else {
+
+        //Never happend so far, but just in case,
+        //exit cleanly and remove pid file
+        std::printf("Received garbage. Exiting.\n");
+
+        remove(pidName.c_str());
+
+        return 1;
+    }
+}
index 19f10c17f3b2ed7c3ac9a51915b40a7e2354aa06..78b378ed05ff22d58c01f00469a085f84d04204f 100755 (executable)
@@ -122,6 +122,7 @@ sub mimosis_register_write_indirect
 }
 
 
+
 sub mimosis_register_read
 {
     my ( $fpga, $mimosis_reg, $singleaccess) = @_;
@@ -695,12 +696,55 @@ sub mimosis_dacscan_sf
 }
 
 
-
 sub send_params_scurve
 {
-    my ($state, $yi, $rowTrain, $xLow, $xHig, $region, $vcasn, $vphfine) = @_;
-    $vphfine = defined $vphfine ? $vphfine : 0;
-    my $frameWr = "START-" . $state . "-" . $yi . "-" . $rowTrain . "-" . $xLow . "-" . $xHig . "-" . $region . "-" . $vcasn . "-" . $vphfine . "-END";
+    my %params = @_;
+    my $state = $params{'state'};
+    my $ySta = $params{'ySta'};
+    my $yEnd = $params{'yEnd'};
+    my $yTra = $params{'yTra'};
+    my $xSta = $params{'xSta'};
+    my $xEnd = $params{'xEnd'};
+    my $setSta = $params{'setSta'};
+    my $setEnd = $params{'setEnd'};
+    my $setTra = $params{'setTra'};
+    my $setCnt = $params{'setCnt'};
+    my $mod = $params{'mod'};
+    my $region = $params{'region'};
+    my $vcasn= $params{'vcasn'};
+    my $singleAccess = $params{'singleAccess'};
+
+    $state = defined $state ? $state : "DONE";
+    $ySta = defined $ySta ? $ySta : 0;
+    $yEnd = defined $yEnd ? $yEnd : 0;
+    $yTra = defined $yTra ? $yTra : 0;
+    $xSta = defined $xSta ? $xSta : 0;
+    $xEnd = defined $xEnd ? $xEnd : 0;
+    $setSta = defined $setSta ? $setSta : 0;
+    $setEnd = defined $setEnd ? $setEnd : 0;
+    $setTra = defined $setTra ? $setTra : 1;
+    $setCnt = defined $setCnt ? $setCnt : 0;
+    $mod = defined $mod ? $mod : 3;
+    $region = defined $region ? $region : A;
+    $vcasn= defined $vcasn ? $vcasn : 0;
+    $singleAccess= defined $singleAccess ? $singleAccess : 0;
+
+    my $frameWr = "START-" .
+      $state . "-" .
+      $ySta . "-" .
+      $yEnd . "-" .
+      $yTra . "-" .
+      $xSta . "-" .
+      $xEnd . "-" .
+      $setSta . "-" .
+      $setEnd . "-" .
+      $setTra . "-" .
+      $setCnt . "-" .
+      $mod . "-" .
+      $region . "-" .
+      $vcasn . "-" .
+      $singleAccess . "-END";
+
     my $pipeNameWr = "/tmp/scurveipipe";
     my $fdPipeWr = POSIX::open($pipeNameWr, &POSIX::O_WRONLY);
     POSIX::write($fdPipeWr,$frameWr,length($frameWr));
@@ -713,7 +757,8 @@ sub kill_proc_by_pid_file
 {
     my ($pidName) = @_;
 
-    my $pidFile = POSIX::open($pidName, &POSIX::O_RDONLY) or die "hldprint already killed probably\n";
+    my $pidFile = POSIX::open($pidName, &POSIX::O_RDONLY)
+      or die "hldprint already killed probably\n";
     my $buf;
     my $bytes = POSIX::read($pidFile,$buf,10);
     POSIX::close($pidFile);
@@ -748,150 +793,97 @@ sub mimosis_scan_region
 {
     my %params = @_;
     my $fpga = $params{'fpga'};
-    my $pulseonly = $params{'pulseonly'};
-    my $region = $params{'region'};
-    my $ySta = $params{'firstrow'};
-    my $yEnd = $params{'lastrow'};
-    my $setSta = $params{'firstset'};
-    my $setEnd = $params{'lastset'};
-    my $setDiv = $params{'setdiv'};
-    my $setTime = $params{'settime'};
     my $slow = $params{'slow'};
     my $a = $params{'a'};
-    my $yTra = $params{'rowsatonce'};
-    my $printset = $params{'printset'};
-    my $printrow = $params{'printrow'};
-    my $printall = $params{'printall'};
-    my $analogAlimA = $params{'analogAlimA'};
-    my $analogAlimB = $params{'analogAlimB'};
-    my $analogDlimA = $params{'analogDlimA'};
-    my $analogDlimB = $params{'analogDlimB'};
-    my $modpulse = $params{'modpulse'};
-
-    defined $fpga or die "Mimosis::mimosis_scan_region: Must provide $fpga.";
-    defined $region or die "Mimosis::mimosis_scan_region: Must provide $region.";
-
-    my %colLim = (
+    my $region = $params{'region'};
+    my $ySta = $params{'ySta'};
+    my $yEnd = $params{'yEnd'};
+    my $yTra = $params{'yTra'};
+    my $xSta = $params{'xSta'};
+    my $xEnd = $params{'xEnd'};
+    my $setSta = $params{'setSta'};
+    my $setEnd = $params{'setEnd'};
+    my $setTra = $params{'setTra'};
+    my $setCnt = $params{'setCnt'};
+    my $analogalima = $params{'analogalima'};
+    my $analogalimb = $params{'analogalimb'};
+    my $analogdlima = $params{'analogdlima'};
+    my $analogdlimb = $params{'analogdlimb'};
+    my $mod = $params{'mod'};
+
+    defined $fpga or die "mimosis::mimosis_scan_region: must provide $fpga.";
+    defined $region or die "mimosis::mimosis_scan_region: must provide $region.";
+
+    my %collim = (
         'A' => [   0, 127 ],
         'B' => [ 128, 511 ],
         'C' => [ 512, 895 ],
         'D' => [ 896, 1023 ]
         );
 
-    %rowAdd     = ( 'A' => 4, 'B' => 2, 'C' => 2, 'D' => 4 );
-
-    %regBitHash = ( 'A' => 0, 'B' => 1, 'C' => 2, 'D' => 3 );
-
-    my $regBit = $regBitHash{$region};
+    %rowadd     = ( 'A' => 4, 'B' => 2, 'C' => 2, 'D' => 4 );
 
+    $slow = defined $slow ? $slow : 10000;
+    $a = defined $a ? $a : 0;
     $ySta = defined $ySta ? $ySta : 0;
     $yEnd = defined $yEnd ? $yEnd : 504;
+    $yTra = defined $yTra ? $yTra : $rowadd{$region};
+    $xSta = defined $xSta ? $xSta : $collim{$region}[0];
+    $xEnd = defined $xEnd ? $xEnd : $collim{$region}[1];
     $setSta = defined $setSta ? $setSta : 0x0;
     $setEnd = defined $setEnd ? $setEnd : 0xff;
-    $setDiv = defined $setDiv ? $setDiv : 1;
-    $setTime = defined $setTime ? $setTime : 1000;
-    $slow = defined $slow ? $slow : 10000;
-    $a = defined $a ? $a : 0;
-    $yTra = defined $yTra ? $yTra : $rowAdd{$region};
-    $printset = defined $printset ? 1 : 0;
-    $printrow = defined $printrow ? 1 : 0;
-    $printall = defined $printall ? 1 : 0;
-    $pixpulseA_A = defined $pixpulseA_A ? $pixpulseA_A : 25;
-    $pixpulseA_B = defined $pixpulseA_B ? $pixpulseA_B : 75;
-    $pixpulseD_A = defined $pixpulseD_A ? $pixpulseD_A : 0;
-    $pixpulseD_B = defined $pixpulseD_B ? $pixpulseD_B : 0;
-    $modpulse = defined $modpulse ? $modpulse : 3;
-
-    Mimosis::mimosis_register_write( $fpga, 0x0020, 0x40, $a ); usleep($slow); #EN_PIXELMASK to 0 for pulse
-    Mimosis::mimosis_instr_write( $fpga,  0x3f ); usleep($slow); #INSTR select all pixels
-    Mimosis::mimosis_instr_write( $fpga,  0x04 ); usleep($slow); #INSTR reset mask
-    Mimosis::mimosis_instr_write( $fpga,  0x3e ); usleep($slow); #INSTR unselect all pixels
-    Mimosis::mimosis_register_write( $fpga, 0x0066,   $pixpulseA_A & 0x00ff       , $a ); usleep($slow); #analog pulsing pulse A, limit A
-    Mimosis::mimosis_register_write( $fpga, 0x0166, ( $pixpulseA_A & 0xff00 ) >> 8, $a ); usleep($slow);
-    Mimosis::mimosis_register_write( $fpga, 0x0076,   $pixpulseA_B & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse A, limit B
-    Mimosis::mimosis_register_write( $fpga, 0x0176, ( $pixpulseA_B & 0xff00 ) >> 8, $a ); usleep($slow);
-    Mimosis::mimosis_register_write( $fpga, 0x0067,   $pixpulseD_A & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse D, limit A
-    Mimosis::mimosis_register_write( $fpga, 0x0167, ( $pixpulseD_A & 0xff00 ) >> 8, $a ); usleep($slow);
-    Mimosis::mimosis_register_write( $fpga, 0x0077,   $pixpulseD_B & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse D, limit B
-    Mimosis::mimosis_register_write( $fpga, 0x0177, ( $pixpulseD_B & 0xff00 ) >> 8, $a ); usleep($slow);
-    Mimosis::mimosis_register_write( $fpga, 0x007d, $modpulse, $a ); usleep($slow); #set modpulse. possible values: 1f/1, 1f/2, 1f/4, 1f/8, 1f/16, 1f/32, 1f/64, 1f/128
-
-
-    for ( my $yOff = $ySta;
-          $yOff <= $yEnd;
-          $yOff+=$yTra ) {
-
-        my $y = $yOff;
-
-        for ( ;
-              $y < $yOff+$yTra && $y <= $yEnd;
-              $y+=1 ) {
-
-            if( $printrow || $printall ) { printf("row: $y\n"); }
-
-            my $regAdd = $y/8;
-            my $regBit   = $y%8;
-            my $regWord = ( $regAdd << 8 ) + 0x84;
-            Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow);
-            Mimosis::mimosis_instr_write( $fpga,  0x27 ); usleep($slow); #INSTR select all pixels
-            Mimosis::mimosis_instr_write( $fpga,  0x05 ); usleep($slow); #INSTR set mask pulse
-            Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise)
-            Mimosis::mimosis_instr_write( $fpga,  0x3e ); usleep($slow); #INSTR unselect all pixels
-        }
-
-        unless($pulseonly)
-        {
-            my $yTraSend = $yEnd-$yOff<$yTra ? $yEnd-$yOff : $yTra;
-            send_params_scurve("TAKEDATA", $yOff, $yTraSend, $colLim{$region}[0], $colLim{$region}[1], $region, 0);
-            await_ack();
-
-            my $setCnt = 0;
-            for my $set (reverse ($setSta .. $setEnd) )
-            {
-                $setCnt = $setCnt + 1;
-                if( ($setCnt-1)%$setDiv != 0) { next; }
-
-                send_params_scurve("NEXTVPH", 0, 0, 0, 0, 0, 0, $set);
-                await_ack();
-
-                my $pulseMsg = ($set << 24) + 0x00c00000;
-                trb_register_write_mem( $fpga, 0xa209, 0, [ $pulseMsg ], 1 ); usleep($slow);
-                # Mimosis::mimosis_register_write( $fpga, 0x0046, $set, $a ); usleep($setTime);
-                Mimosis::mimosis_register_write( $fpga, 0x0046, $set, $a );
-
-                if( $printset || $printall ) { printf("set: $set\n"); }
-            }
-
-            Mimosis::mimosis_instr_write( $fpga, 0x3f ); usleep($slow);
-            Mimosis::mimosis_instr_write( $fpga, 0x04 ); usleep($slow); #INSTR set mask pulse
-            Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR set mask pulse
-
-            trb_register_write_mem( $fpga, 0xa209, 0, [ 0x00400000 ], 1 ); usleep($slow);
-            send_params_scurve("WAITDAQ", 0, 0, 0, 0, 0, 0);
-            await_ack();
-            trb_register_write_mem( $fpga, 0xa209, 0, [ 0x00000000 ], 1 ); usleep($slow);
-        }
-    }
+    $setTra = defined $setTra ? $setTra : 1;
+    $setCnt = defined $setCnt ? $setCnt : 4000;
+    $pixpulsea_a = defined $pixpulsea_a ? $pixpulsea_a : 25;
+    $pixpulsea_b = defined $pixpulsea_b ? $pixpulsea_b : 75;
+    $pixpulsed_a = defined $pixpulsed_a ? $pixpulsed_a : 0;
+    $pixpulsed_b = defined $pixpulsed_b ? $pixpulsed_b : 0;
+    $mod = defined $mod ? $mod : 3;
+
+    Mimosis::mimosis_register_write( $fpga, 0x0020, 0x40, $a ); usleep($slow); #en_pixelmask to 0 for pulse
+    Mimosis::mimosis_instr_write( $fpga,  0x3f ); usleep($slow); #instr select all pixels
+    Mimosis::mimosis_instr_write( $fpga,  0x04 ); usleep($slow); #instr reset mask
+    Mimosis::mimosis_instr_write( $fpga,  0x3e ); usleep($slow); #instr unselect all pixels
+    Mimosis::mimosis_register_write( $fpga, 0x0066,   $pixpulsea_a & 0x00ff       , $a ); usleep($slow); #analog pulsing pulse a, limit a
+    Mimosis::mimosis_register_write( $fpga, 0x0166, ( $pixpulsea_a & 0xff00 ) >> 8, $a ); usleep($slow);
+    Mimosis::mimosis_register_write( $fpga, 0x0076,   $pixpulsea_b & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse a, limit b
+    Mimosis::mimosis_register_write( $fpga, 0x0176, ( $pixpulsea_b & 0xff00 ) >> 8, $a ); usleep($slow);
+    Mimosis::mimosis_register_write( $fpga, 0x0067,   $pixpulsed_a & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse d, limit a
+    Mimosis::mimosis_register_write( $fpga, 0x0167, ( $pixpulsed_a & 0xff00 ) >> 8, $a ); usleep($slow);
+    Mimosis::mimosis_register_write( $fpga, 0x0077,   $pixpulsed_b & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse d, limit b
+    Mimosis::mimosis_register_write( $fpga, 0x0177, ( $pixpulsed_b & 0xff00 ) >> 8, $a ); usleep($slow);
+    Mimosis::mimosis_register_write( $fpga, 0x007d, $mod, $a ); usleep($slow); #set modpulse. possible values: 1f/1, 1f/2, 1f/4, 1f/8, 1f/16, 1f/32, 1f/64, 1f/128
+
+    send_params_scurve(
+                       state => "TAKEDATA",
+                       ySta  => $ySta,
+                       yEnd  => $yEnd,
+                       yTra  => $yTra,
+                       xSta  => $xSta,
+                       xEnd  => $xEnd,
+                       setSta => $setSta,
+                       setEnd => $setEnd,
+                       setTra => $setTra,
+                       setCnt => $setCnt,
+                       mod    => $mod,
+                       region => $region,
+                       vcasn  => 0,
+                       singleAccess => $a
+                      );
+    await_ack();
 }
 
 
-
-sub mimosis_scan_pixel
+sub mimosis_pulse_region
 {
     my %params = @_;
     my $fpga = $params{'fpga'};
-    my $x = $params{'x'};
-    my $y = $params{'y'};
-    my $add = $params{'add'};
-    my $pulseonly = $params{'pulseonly'};
-    my $setSta = $params{'firstset'};
-    my $setEnd = $params{'lastset'};
-    my $setDiv = $params{'setdiv'};
-    my $setTime = $params{'settime'};
     my $slow = $params{'slow'};
     my $a = $params{'a'};
-    my $printset = $params{'printset'};
-    my $printall = $params{'printall'};
+    my $region = $params{'region'};
+    my $ySta = $params{'ySta'};
+    my $yEnd = $params{'yEnd'};
+    my $yTra = $params{'yTra'};
     my $analogAlimA = $params{'analogAlimA'};
     my $analogAlimB = $params{'analogAlimB'};
     my $analogDlimA = $params{'analogDlimA'};
@@ -899,17 +891,15 @@ sub mimosis_scan_pixel
     my $modpulse = $params{'modpulse'};
 
     defined $fpga or die "Mimosis::mimosis_scan_region: Must provide --fpga.";
-    defined $x or die "Mimosis::mimosis_scan_region: Must provide --x.";
-    defined $y or die "Mimosis::mimosis_scan_region: Must provide --y.";
+    defined $region or die "mimosis::mimosis_scan_region: must provide --region.";
+
+    %rowadd     = ( 'A' => 4, 'B' => 2, 'C' => 2, 'D' => 4 );
 
-    $setSta = defined $setSta ? $setSta : 0x0;
-    $setEnd = defined $setEnd ? $setEnd : 0xff;
-    $setDiv = defined $setDiv ? $setDiv : 1;
-    $setTime = defined $setTime ? $setTime : 1000;
     $slow = defined $slow ? $slow : 10000;
     $a = defined $a ? $a : 0;
-    $printset = defined $printset ? 1 : 0;
-    $printall = defined $printall ? 1 : 0;
+    $ySta = defined $ySta ? $ySta : 0;
+    $yEnd = defined $yEnd ? $yEnd : 503;
+    $yTra = defined $yTra ? $yTra : $rowadd{$region};
     $pixpulseA_A = defined $pixpulseA_A ? $pixpulseA_A : 25;
     $pixpulseA_B = defined $pixpulseA_B ? $pixpulseA_B : 75;
     $pixpulseD_A = defined $pixpulseD_A ? $pixpulseD_A : 0;
@@ -918,12 +908,9 @@ sub mimosis_scan_pixel
 
     Mimosis::mimosis_register_write( $fpga, 0x0020, 0x40, $a ); usleep($slow); #EN_PIXELMASK to 0 for pulse
 
-    unless(defined $add)
-    {
-        Mimosis::mimosis_instr_write( $fpga,  0x3f ); usleep($slow); #INSTR select all pixels
-        Mimosis::mimosis_instr_write( $fpga,  0x04 ); usleep($slow); #INSTR reset mask
-        Mimosis::mimosis_instr_write( $fpga,  0x3e ); usleep($slow); #INSTR unselect all pixels
-    }
+    Mimosis::mimosis_instr_write( $fpga,  0x3f ); usleep($slow); #INSTR select all pixels
+    Mimosis::mimosis_instr_write( $fpga,  0x04 ); usleep($slow); #INSTR reset mask
+    Mimosis::mimosis_instr_write( $fpga,  0x3e ); usleep($slow); #INSTR unselect all pixels
 
     Mimosis::mimosis_register_write( $fpga, 0x0066,   $pixpulseA_A & 0x00ff       , $a ); usleep($slow); #analog pulsing pulse A, limit A
     Mimosis::mimosis_register_write( $fpga, 0x0166, ( $pixpulseA_A & 0xff00 ) >> 8, $a ); usleep($slow);
@@ -935,59 +922,139 @@ sub mimosis_scan_pixel
     Mimosis::mimosis_register_write( $fpga, 0x0177, ( $pixpulseD_B & 0xff00 ) >> 8, $a ); usleep($slow);
     Mimosis::mimosis_register_write( $fpga, 0x007d, $modpulse, $a ); usleep($slow); #set modpulse. possible values: 1f/1, 1f/2, 1f/4, 1f/8, 1f/16, 1f/32, 1f/64, 1f/128
 
+    for( my $yOff = $ySta;
+        $yOff <= $yEnd;
+        $yOff += $yTra)
     {
-        my $regAdd = $x/16;  #region address
-        my $regBit   = ($x/2)%8;  #double column in region
-        my $regWord = $regAdd << 8;
-        if    (($x%2 == 1)) { $regWord += 0x82; }
-        elsif (($x%2 == 0)) { $regWord += 0x81; }
-        Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow);
-    }
-
-    {
-        my $regAdd = $y/8;
-        my $regBit   = $y%8;
-        my $regWord = ( $regAdd << 8 ) + 0x84;
-        Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow);
-    }
-
-    Mimosis::mimosis_instr_write( $fpga,  0x05 ); usleep($slow); #INSTR set mask pulse
-    Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise)
-
-    unless($pulseonly)
-    {
-        send_params_scurve("TAKEDATA", $y, 1, $x, $x+1, 0, 0);
-        await_ack();
-
-        my $setCnt = 0;
-        for my $set (reverse ($setSta .. $setEnd) )
-        {
-            $setCnt = $setCnt + 1;
-            if( ($setCnt-1)%$setDiv != 0) { next; }
-
-            my $pulseMsg = ($set << 24) + 0x00c00000;
-            trb_register_write_mem( $fpga, 0xa209, 0, [ $pulseMsg ], 1 ); usleep($slow);
-            Mimosis::mimosis_register_write( $fpga, 0x0046, $set, $a ); usleep($setTime);
-
-            if( $printset || $printall ) { printf("set: $set\n"); }
-        }
+        my $y = $yOff;
 
-        unless(defined $add)
+        for(; ($y<$yOff+$yTra) && ($y <= $yEnd); $y+=1)
         {
-            Mimosis::mimosis_instr_write( $fpga,  0x3f ); usleep($slow); #INSTR select all pixels
-            Mimosis::mimosis_instr_write( $fpga,  0x04 ); usleep($slow); #INSTR reset mask
+            my $regAdd = $y/8;
+            my $regBit   = $y%8;
+            my $regWord = ( $regAdd << 8 ) + 0x84;
+            Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow);
+            Mimosis::mimosis_instr_write( $fpga,  0x27 ); usleep($slow); #INSTR select all pixels
+            Mimosis::mimosis_instr_write( $fpga,  0x05 ); usleep($slow); #INSTR set mask pulse
+            Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise)
             Mimosis::mimosis_instr_write( $fpga,  0x3e ); usleep($slow); #INSTR unselect all pixels
         }
-
-        trb_register_write_mem( $fpga, 0xa209, 0, [ 0x00400000 ], 1 ); usleep($slow);
-        send_params_scurve("WAITDAQ", 0, 0, 0, 0, 0, 0);
-        await_ack();
-        trb_register_write_mem( $fpga, 0xa209, 0, [ 0x00000000 ], 1 ); usleep($slow);
     }
 }
 
 
 
+# sub mimosis_scan_pixel
+# {
+#     my %params = @_;
+#     my $fpga = $params{'fpga'};
+#     my $x = $params{'x'};
+#     my $y = $params{'y'};
+#     my $add = $params{'add'};
+#     my $pulseonly = $params{'pulseonly'};
+#     my $setSta = $params{'firstset'};
+#     my $setEnd = $params{'lastset'};
+#     my $setDiv = $params{'setdiv'};
+#     my $setTime = $params{'settime'};
+#     my $slow = $params{'slow'};
+#     my $a = $params{'a'};
+#     my $printall = $params{'printall'};
+#     my $analogAlimA = $params{'analogAlimA'};
+#     my $analogAlimB = $params{'analogAlimB'};
+#     my $analogDlimA = $params{'analogDlimA'};
+#     my $analogDlimB = $params{'analogDlimB'};
+#     my $modpulse = $params{'modpulse'};
+
+#     defined $fpga or die "Mimosis::mimosis_scan_region: Must provide --fpga.";
+#     defined $x or die "Mimosis::mimosis_scan_region: Must provide --x.";
+#     defined $y or die "Mimosis::mimosis_scan_region: Must provide --y.";
+
+#     $setSta = defined $setSta ? $setSta : 0x0;
+#     $setEnd = defined $setEnd ? $setEnd : 0xff;
+#     $setDiv = defined $setDiv ? $setDiv : 1;
+#     $setTime = defined $setTime ? $setTime : 1000;
+#     $slow = defined $slow ? $slow : 10000;
+#     $a = defined $a ? $a : 0;
+#     $printset = defined $printset ? 1 : 0;
+#     $printall = defined $printall ? 1 : 0;
+#     $pixpulseA_A = defined $pixpulseA_A ? $pixpulseA_A : 25;
+#     $pixpulseA_B = defined $pixpulseA_B ? $pixpulseA_B : 75;
+#     $pixpulseD_A = defined $pixpulseD_A ? $pixpulseD_A : 0;
+#     $pixpulseD_B = defined $pixpulseD_B ? $pixpulseD_B : 0;
+#     $modpulse = defined $modpulse ? $modpulse : 3;
+
+#     Mimosis::mimosis_register_write( $fpga, 0x0020, 0x40, $a ); usleep($slow); #EN_PIXELMASK to 0 for pulse
+
+#     unless(defined $add)
+#     {
+#         Mimosis::mimosis_instr_write( $fpga,  0x3f ); usleep($slow); #INSTR select all pixels
+#         Mimosis::mimosis_instr_write( $fpga,  0x04 ); usleep($slow); #INSTR reset mask
+#         Mimosis::mimosis_instr_write( $fpga,  0x3e ); usleep($slow); #INSTR unselect all pixels
+#     }
+
+#     Mimosis::mimosis_register_write( $fpga, 0x0066,   $pixpulseA_A & 0x00ff       , $a ); usleep($slow); #analog pulsing pulse A, limit A
+#     Mimosis::mimosis_register_write( $fpga, 0x0166, ( $pixpulseA_A & 0xff00 ) >> 8, $a ); usleep($slow);
+#     Mimosis::mimosis_register_write( $fpga, 0x0076,   $pixpulseA_B & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse A, limit B
+#     Mimosis::mimosis_register_write( $fpga, 0x0176, ( $pixpulseA_B & 0xff00 ) >> 8, $a ); usleep($slow);
+#     Mimosis::mimosis_register_write( $fpga, 0x0067,   $pixpulseD_A & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse D, limit A
+#     Mimosis::mimosis_register_write( $fpga, 0x0167, ( $pixpulseD_A & 0xff00 ) >> 8, $a ); usleep($slow);
+#     Mimosis::mimosis_register_write( $fpga, 0x0077,   $pixpulseD_B & 0x00ff       , $a ); usleep($slow); # analog pulsing pulse D, limit B
+#     Mimosis::mimosis_register_write( $fpga, 0x0177, ( $pixpulseD_B & 0xff00 ) >> 8, $a ); usleep($slow);
+#     Mimosis::mimosis_register_write( $fpga, 0x007d, $modpulse, $a ); usleep($slow); #set modpulse. possible values: 1f/1, 1f/2, 1f/4, 1f/8, 1f/16, 1f/32, 1f/64, 1f/128
+
+#     {
+#         my $regAdd = $x/16;  #region address
+#         my $regBit   = ($x/2)%8;  #double column in region
+#         my $regWord = $regAdd << 8;
+#         if    (($x%2 == 1)) { $regWord += 0x82; }
+#         elsif (($x%2 == 0)) { $regWord += 0x81; }
+#         Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow);
+#     }
+
+#     {
+#         my $regAdd = $y/8;
+#         my $regBit   = $y%8;
+#         my $regWord = ( $regAdd << 8 ) + 0x84;
+#         Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow);
+#     }
+
+#     Mimosis::mimosis_instr_write( $fpga,  0x05 ); usleep($slow); #INSTR set mask pulse
+#     Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise)
+
+#     unless($pulseonly)
+#     {
+#         send_params_scurve("TAKEDATA", $y, 1, $x, $x+1, 0, 0);
+#         await_ack();
+
+#         my $setCnt = 0;
+#         for my $set (reverse ($setSta .. $setEnd) )
+#         {
+#             $setCnt = $setCnt + 1;
+#             if( ($setCnt-1)%$setDiv != 0) { next; }
+
+#             my $pulseMsg = ($set << 24) + 0x00c00000;
+#             trb_register_write_mem( $fpga, 0xa209, 0, [ $pulseMsg ], 1 ); usleep($slow);
+#             Mimosis::mimosis_register_write( $fpga, 0x0046, $set, $a ); usleep($setTime);
+
+#             if( $printset || $printall ) { printf("set: $set\n"); }
+#         }
+
+#         unless(defined $add)
+#         {
+#             Mimosis::mimosis_instr_write( $fpga,  0x3f ); usleep($slow); #INSTR select all pixels
+#             Mimosis::mimosis_instr_write( $fpga,  0x04 ); usleep($slow); #INSTR reset mask
+#             Mimosis::mimosis_instr_write( $fpga,  0x3e ); usleep($slow); #INSTR unselect all pixels
+#         }
+
+#         trb_register_write_mem( $fpga, 0xa209, 0, [ 0x00400000 ], 1 ); usleep($slow);
+#         send_params_scurve("WAITDAQ", 0, 0, 0, 0, 0, 0);
+#         await_ack();
+#         trb_register_write_mem( $fpga, 0xa209, 0, [ 0x00000000 ], 1 ); usleep($slow);
+#     }
+# }
+
+
+
 sub mimosis_mask
 {
     my %params = @_;
@@ -1312,6 +1379,33 @@ END_MESSAGE
 }
 
 
+
+sub help_analyse {
+    my $message = <<'END_MESSAGE';
+
+usage: mimosis [GLOBAL OPTIONS] analyse [COMMAND OPTIONS]
+
+Analyse data from scurve scans. Needs to be executed from the run folder, where the METADATA file is.
+
+GLOBAL OPTIONS are:
+    -f, --fpga=HEX      ->  Hex address of the FPGA. Defaults to 0xa000.
+    -s, --slow=NUM      ->  Execute I2C commands with a pause of NUM microseconds in between.
+    -a, --singleaccess  ->  Select single access mode.
+    -h, --help          ->  Print this or <command> specific help.
+
+COMMAND OPTIONS are:
+        --vcasn=NUM     ->  Analyse data from only the run where VCASN is NUM.
+    -t, --threads       ->  Number of threads to use. Defaults to 1.
+
+    -h, --help          ->  Print this help.
+END_MESSAGE
+
+    print $message;
+    exit 0;
+}
+
+
+
 sub help_mask {
     my $message = <<'END_MESSAGE';
 
index c7ef7f5d3016dc086a2a0e64929503781b34ac77..5d2fffc010b056ebae7208a538c19d8e9add7c74 100755 (executable)
@@ -9,12 +9,34 @@ use Data::Dump qw(dump);
 use File::Copy;
 
 
+
 $SIG{INT} = sub {
     Mimosis::kill_proc_by_pid_file("/tmp/hldprint-pid");
     die "\nAbort.\n"
 };
 
 
+
+my %dacs = (
+    IBIAS => 0x0040,
+    ITHR  => 0x0041,
+    IDB   => 0x0042,
+    VRESET => 0x0043,
+    VPL    => 0x0044,
+    VPH    => 0x0045,
+    VPH_FINE => 0x0046,
+    VCASP    => 0x0047,
+    VCASNA   => 0x0048,
+    VCASNB   => 0x0049,
+    VCASNC   => 0x004a,
+    VCASND   => 0x004b,
+    VCASN2   => 0x004c,
+    VCLIP    => 0x004d,
+    IBUFBIAS => 0x004e
+    );
+
+
+
 #global
 my ( $fpga, $a, $slow );
 
@@ -27,9 +49,10 @@ my ( $ikf, $name, $imagefileonly, $cleanup_dacscan, $printall_dacscan );
 #scurves
 my ( $pulseOnlySc,   $regionSc, $xSc, $ySc, $addSc, $resetSc,
      $yStaSc,    $yEndSc,     $yStepSc,
+     $xStaSc,    $xEndSc,
      $setStaSc,    $setEndSc,
      $setStepSc,     $vcasnSc, $vcasnStaSc,  $vcasnEndSc,
-     $vcasnStepSc,   $setTimeSc,     $yTraSc,  $printSetSc, $printDacSc,
+     $vcasnStepSc,   $setCntSc,     $yTraSc,  $printSetSc, $printDacSc,
      $printRowSc,    $printAllSc,    $analogAlimASc,
      $analogAlimBSc, $analogDlimASc, $analogDlimBSc, $modpulseSc );
 
@@ -38,6 +61,8 @@ my ( $region_mask,  $row_mask,       $col_mask,
      $maskall_mask, $unmaskall_mask, $hline_mask,
      $vline_mask,   $square_mask,    $printall_mask );
 
+#analyse
+my ( $vcasnAn, $threadsAn );
 
 my @ARGV_bak = @ARGV;
 
@@ -83,10 +108,12 @@ my $res = GetOptions (
                 "firstrow=s"        => \$yStaSc,
                 "lastrow=s"         => \$yEndSc,
                 "rowdiv=s"          => \$yStepSc,
+                "firstcol=s"        => \$xStaSc,
+                "lastcol=s"         => \$xEndSc,
                 "firstset=s"        => \$setStaSc,
                 "lastset=s"         => \$setEndSc,
                 "setdiv=s"          => \$setStepSc,
-                "settime=s"         => \$setTimeSc,
+                "setcounts=s"       => \$setCntSc,
                 "firstvcasn=s"      => \$vcasnStaSc,
                 "lastvcasn=s"       => \$vcasnEndSc,
                 "vcasndiv=s"        => \$vcasnStepSc,
@@ -106,6 +133,15 @@ my $res = GetOptions (
                 }
             },
         },
+        analyse => {
+            options => {
+                "vcasn"         => \$vcasnAn,
+                "threads|t"     => \$threadsAn,
+                'help|h'        => {
+                    handler => \&Mimosis::help_analyse,
+                }
+            },
+        },
         mask => {
             options => {
                 "region|r=s"        => \$region_mask,
@@ -235,24 +271,6 @@ elsif( $res->{subcommand}[0] eq 'dacscan' )
 elsif( $res->{subcommand}[0] eq 'scurves' )
 {
 
-    my %dacs = (
-        IBIAS => 0x0040,
-        ITHR  => 0x0041,
-        IDB   => 0x0042,
-        VRESET => 0x0043,
-        VPL    => 0x0044,
-        VPH    => 0x0045,
-        VPH_FINE => 0x0046,
-        VCASP    => 0x0047,
-        VCASNA   => 0x0048,
-        VCASNB   => 0x0049,
-        VCASNC   => 0x004a,
-        VCASND   => 0x004b,
-        VCASN2   => 0x004c,
-        VCLIP    => 0x004d,
-        IBUFBIAS => 0x004e
-        );
-
     my %regCharToStr = (
         A => 'VCASNA',
         B => 'VCASNB',
@@ -260,6 +278,27 @@ elsif( $res->{subcommand}[0] eq 'scurves' )
         D => 'VCASND'
         );
 
+    if( defined $pulseOnlySc )
+    {
+        Mimosis::mimosis_pulse_region(
+            fpga        => $fpga,
+            slow        => $slow,
+            a           => $a,
+            region      => $regionSc,
+            ySta        => $yStaSc,
+            yEnd        => $yEndSc,
+            yTra        => $yTraSc,
+            xSta        => $xStaSc,
+            xEnd        => $xEndSc,
+            analogAlimA => $analogAlimASc,
+            analogAlimB => $analogAlimBSc,
+            analogDlimA => $analogDlimASc,
+            analogDlimB => $analogDlimBSc,
+            mod         => $modpulseSc,
+        );
+        exit 0;
+    }
+
     if( defined $regionSc )
     {
         my $vcasnStr = $regCharToStr{$regionSc};
@@ -268,10 +307,7 @@ elsif( $res->{subcommand}[0] eq 'scurves' )
         $vcasnEndSc = defined $vcasnEndSc ? $vcasnEndSc : $vcasnStaSc;
         $vcasnStepSc = defined $vcasnStepSc ? $vcasnStepSc : 1;
 
-        unless($pulseOnlySc)
-        {
-            system("/d/jspc37/mimosis/analysis/mbs/dabc/build/bin/hldprint mbss://localhost:36789 &");
-        }
+        system("/d/jspc37/mimosis/cpp/build/scurve-scan mbss://localhost:36789 &");
 
         for ( my $vcasnSet = $vcasnStaSc;
               $vcasnSet <= $vcasnEndSc;
@@ -285,103 +321,114 @@ elsif( $res->{subcommand}[0] eq 'scurves' )
                 fpga        => $fpga,
                 slow        => $slow,
                 a           => $a,
-                pulseonly   => $pulseOnlySc,
-                add         => $addSc,
                 region      => $regionSc,
-                firstrow    => $yStaSc,
-                lastrow     => $yEndSc,
-                rowdiv      => $yStepSc,
-                rowsatonce  => $yTraSc,
-                firstset    => $setStaSc,
-                lastset     => $setEndSc,
-                setdiv      => $setStepSc,
-                settime     => $setTimeSc,
-                printset    => $printSetSc,
-                printrow    => $printRowSc,
-                printall    => $printAllSc,
+                ySta        => $yStaSc,
+                yEnd        => $yEndSc,
+                yTra        => $yTraSc,
+                xSta        => $xStaSc,
+                xEnd        => $xEndSc,
+                setSta      => $setStaSc,
+                setEnd      => $setEndSc,
+                setTra      => $setStepSc,
+                setCnt      => $setCntSc,
                 analogAlimA => $analogAlimASc,
                 analogAlimB => $analogAlimBSc,
                 analogDlimA => $analogDlimASc,
                 analogDlimB => $analogDlimBSc,
-                modpulse    => $modpulseSc,
+                mod         => $modpulseSc,
             );
 
-            unless($pulseOnlySc)
-            {
-                Mimosis::send_params_scurve("FIT", 0,0,0,0,$regCharToStr{$regionSc},$vcasnSet);
-                Mimosis::await_ack();
-            }
-        }
-
-        unless($pulseOnlySc)
-        {
-            Mimosis::send_params_scurve("DONE", 0,0,0,0,0,0);
+            Mimosis::send_params_scurve(
+                                        state => "FIT",
+                                        region => $regCharToStr{$regionSc},
+                                        vcasn => $vcasnSet
+                                       );
             Mimosis::await_ack();
-            Mimosis::kill_proc_by_pid_file("/tmp/hldprint-pid");
         }
+
+        Mimosis::send_params_scurve( state => "DONE" );
+        Mimosis::await_ack();
+        Mimosis::kill_proc_by_pid_file("/tmp/hldprint-pid");
         exit 0;
 
     } elsif (defined $xSc && defined $ySc && defined $vcasnSc) {
 
-        my $vcasnVal = Mimosis::mimosis_register_read( $fpga, $dacs{$vcasnSc}, $a );
-        $vcasnStaSc = defined $vcasnStaSc ? $vcasnStaSc : $vcasnVal;
-        $vcasnEndSc = defined $vcasnEndSc ? $vcasnEndSc : $vcasnStaSc;
-        $vcasnStepSc = defined $vcasnStepSc ? $vcasnStepSc : 1;
-
-        unless($pulseOnlySc)
-        {
-            system("/d/jspc37/mimosis/analysis/mbs/dabc/build/bin/hldprint mbss://localhost:36789 &");
-        }
+        # my $vcasnVal = Mimosis::mimosis_register_read( $fpga, $dacs{$vcasnSc}, $a );
+        # $vcasnStaSc = defined $vcasnStaSc ? $vcasnStaSc : $vcasnVal;
+        # $vcasnEndSc = defined $vcasnEndSc ? $vcasnEndSc : $vcasnStaSc;
+        # $vcasnStepSc = defined $vcasnStepSc ? $vcasnStepSc : 1;
+
+        # unless($pulseOnlySc)
+        # {
+        #     system("/d/jspc37/mimosis/cpp/build/scurve-scan mbss://localhost:36789 &");
+        # }
+
+        # for ( my $vcasnSet = $vcasnStaSc;
+        #       $vcasnSet <= $vcasnEndSc;
+        #       $vcasnSet += $vcasnStepSc ) {
+        #     #set vcasn
+        #     Mimosis::mimosis_register_write( $fpga, $dacs{$vcasnSc}, $vcasnSet, $a ); usleep($slow);
+
+        #     if( $printDacSc || $printAllSc ) { printf("dac: $vcasnSet\n"); }
+
+        #     Mimosis::mimosis_scan_pixel(
+        #         fpga        => $fpga,
+        #         slow        => $slow,
+        #         a           => $a,
+        #         x           => $xSc,
+        #         y           => $ySc,
+        #         pulseonly   => $pulseOnlySc,
+        #         firstset    => $setStaSc,
+        #         lastset     => $setEndSc,
+        #         setdiv      => $setStepSc,
+        #         settime     => $setCntSc,
+        #         printset    => $printSetSc,
+        #         printrow    => $printRowSc,
+        #         printall    => $printAllSc,
+        #         analogAlimA => $analogAlimASc,
+        #         analogAlimB => $analogAlimBSc,
+        #         analogDlimA => $analogDlimASc,
+        #         analogDlimB => $analogDlimBSc,
+        #         modpulse    => $modpulseSc,
+        #     );
+
+        #     unless($pulseOnlySc)
+        #     {
+        #         Mimosis::send_params_scurve("FIT", 0,0,0,0,$vcasnSc,$vcasnSet);
+        #         Mimosis::await_ack();
+        #     }
+        # }
+
+        # unless($pulseOnlySc)
+        # {
+        #     Mimosis::send_params_scurve("DONE", 0,0,0,0,0,0);
+        #     Mimosis::await_ack();
+        #     Mimosis::kill_proc_by_pid_file("/tmp/hldprint-pid");
+        # }
+        # exit 0;
 
-        for ( my $vcasnSet = $vcasnStaSc;
-              $vcasnSet <= $vcasnEndSc;
-              $vcasnSet += $vcasnStepSc ) {
-            #set vcasn
-            Mimosis::mimosis_register_write( $fpga, $dacs{$vcasnSc}, $vcasnSet, $a ); usleep($slow);
+    } else {
 
-            if( $printDacSc || $printAllSc ) { printf("dac: $vcasnSet\n"); }
+        print "Mimosis::mimosis_scan_region: Must provide --region A|B|C|D or --x X and --y Y.\n";
+        exit 1;
+    }
+}
 
-            Mimosis::mimosis_scan_pixel(
-                fpga        => $fpga,
-                slow        => $slow,
-                a           => $a,
-                x           => $xSc,
-                y           => $ySc,
-                pulseonly   => $pulseOnlySc,
-                firstset    => $setStaSc,
-                lastset     => $setEndSc,
-                setdiv      => $setStepSc,
-                settime     => $setTimeSc,
-                printset    => $printSetSc,
-                printrow    => $printRowSc,
-                printall    => $printAllSc,
-                analogAlimA => $analogAlimASc,
-                analogAlimB => $analogAlimBSc,
-                analogDlimA => $analogDlimASc,
-                analogDlimB => $analogDlimBSc,
-                modpulse    => $modpulseSc,
-            );
+elsif( $res->{subcommand}[0] eq 'analyse' )
+{
+    my %regCharToStr = (
+        A => 'VCASNA',
+        B => 'VCASNB',
+        C => 'VCASNC',
+        D => 'VCASND'
+        );
 
-            unless($pulseOnlySc)
-            {
-                Mimosis::send_params_scurve("FIT", 0,0,0,0,$vcasnSc,$vcasnSet);
-                Mimosis::await_ack();
-            }
-        }
+    open(FH, '<', 'METADATA') or die print "Cannot open METADATA. Is this a vild run dir?\n";
 
-        unless($pulseOnlySc)
-        {
-            Mimosis::send_params_scurve("DONE", 0,0,0,0,0,0);
-            Mimosis::await_ack();
-            Mimosis::kill_proc_by_pid_file("/tmp/hldprint-pid");
-        }
-        exit 0;
+    # system("/d/jspc37/mimosis/scripts/pulse/plot-raw.py");
 
-    } else {
 
-        print "Mimosis::mimosis_scan_region: Must provide --region A|B|C|D or --x X and --y Y.\n";
-        exit 1;
-    }
+    exit 0;
 }
 
 elsif( $res->{subcommand}[0] eq 'mask' )
index 535e4ab92cdcee6fc071e64613df7ffb58727af0..0a9636dbd1d287aa2998bfa13ed3a40104c13242 100644 (file)
@@ -31,7 +31,7 @@ for i in range(len(df.loc[:])):
         if df.loc[i][j] != 0:
             xS.append(j)
 
-    print(xS)
+#    print(xS)
 
     if sum(df.loc[i][0:255]) != 0: