Ignore:
Timestamp:
05/23/12 17:06:08 (12 years ago)
Author:
tbretz
Message:
Adapted to the changes in the StateMachineDim. Now (almost) all received services are processed synchronously with the commands and (more important) with the Execute function.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/ratescan.cc

    r13761 r13838  
    1818#include "HeadersFTM.h"
    1919
    20 namespace ba    = boost::asio;
    21 namespace bs    = boost::system;
    22 namespace dummy = ba::placeholders;
     20namespace ba = boost::asio;
     21namespace bs = boost::system;
    2322
    2423using namespace std;
     
    2726
    2827#include "DimDescriptionService.h"
     28#include "DimState.h"
    2929
    3030// ------------------------------------------------------------------------
    3131
    32 class StateMachineRateScan : public StateMachineDim, public DimInfoHandler
     32class StateMachineRateScan : public StateMachineDim
    3333{
    34     /*
    35     int Wrap(boost::function<void()> f)
    36     {
    37         f();
    38         return T::GetCurrentState();
    39     }
    40 
    41     boost::function<int(const EventImp &)> Wrapper(boost::function<void()> func)
    42     {
    43         return bind(&StateMachineMCP::Wrap, this, func);
    44     }*/
    45 
    4634private:
    4735    enum states_t
     
    5442    };
    5543
    56 //    PixelMap fMap;
    57 
    58     DimServiceInfoList fNetwork;
    59 
    60     pair<Time, int> fStatusDim;
    61     pair<Time, int> fStatusFTM;
    62 
    63     DimStampedInfo fDim;
    64     DimStampedInfo fFTM;
    65     DimStampedInfo fRates;
     44    DimServiceInfoListImp fNetwork;
     45
     46    DimVersion fDim;
     47    DimState   fDimFTM;
    6648
    6749    DimDescribedService fDimData;
     
    10587    }
    10688
    107     pair<Time, int> GetNewState(DimStampedInfo &info) const
    108     {
    109         const bool disconnected = info.getSize()==0;
    110 
    111         // Make sure getTimestamp is called _before_ getTimestampMillisecs
    112         const int tsec = info.getTimestamp();
    113         const int tms  = info.getTimestampMillisecs();
    114 
    115         return make_pair(Time(tsec, tms*1000),
    116                          disconnected ? -2 : info.getQuality());
    117     }
    118 
    119     bool CheckEventSize(size_t has, const char *name, size_t size)
    120     {
    121         if (has==size)
     89    bool CheckEventSize(const EventImp &evt, size_t size)
     90    {
     91        if (size_t(evt.GetSize())==size)
    12292            return true;
    12393
    124         if (has==0)
     94        if (evt.GetSize()==0)
    12595            return false;
    12696
    12797        ostringstream msg;
    128         msg << name << " - Received event has " << has << " bytes, but expected " << size << ".";
     98        msg << evt.GetName() << " - Received event has " << evt.GetSize() << " bytes, but expected " << size << ".";
    12999        Fatal(msg);
    130100        return false;
    131101    }
    132102
    133     void infoHandler()
    134     {
    135         DimInfo *curr = getInfo(); // get current DimInfo address
    136         if (!curr)
     103    int HandleTriggerRates(const EventImp &evt)
     104    {
     105        if (!CheckEventSize(evt, sizeof(FTM::DimTriggerRates)))
     106            return GetCurrentState();
     107
     108        if (fThreshold<0/* || fDimFTM.state()!=FTM::kTakingData*/)
     109            return GetCurrentState();
     110
     111        const FTM::DimTriggerRates &sdata = *static_cast<const FTM::DimTriggerRates*>(evt.GetData());
     112
     113        if (++fCounter<0)
     114            return GetCurrentState();
     115
     116        if (fCounter==0)
     117        {
     118            fRate = 0;
     119
     120            memset(fRateBoard, 0,  40*sizeof(double));
     121            memset(fRatePatch, 0, 160*sizeof(double));
     122
     123            fOnTime = 0;
     124            return GetCurrentState();
     125        }
     126/*
     127        if (sdata.fTriggerRate==0)
     128        {
     129            Message("Rate scan stopped due zero trigger rate.");
     130            fThreshold = -1;
    137131            return;
    138 
    139         if (curr==&fFTM)
    140         {
    141             fStatusFTM = GetNewState(fFTM);
     132        }
     133*/
     134
     135        fRate += sdata.fTriggerRate;
     136        for (int i=0; i<40; i++)
     137            fRateBoard[i] += sdata.fBoardRate[i];
     138        for (int i=0; i<160; i++)
     139            fRatePatch[i] += sdata.fPatchRate[i];
     140
     141        double reference = fRate;
     142        if (fReference==kBoard)
     143            reference = fRateBoard[fReferenceIdx];
     144        if (fReference==kPatch)
     145            reference = fRatePatch[fReferenceIdx];
     146
     147        fOnTime += sdata.fOnTime;
     148
     149        reference *= sdata.fElapsedTime;
     150
     151        if ((reference==0 || sqrt(reference)>fResolution*reference) && fCounter<fCounterMax)
     152        {
     153            ostringstream out;
     154            out << "Triggers so far: " << reference;
     155            if (reference>0)
     156                out << " (" << sqrt(reference)/reference << ")";
     157            Info(out);
     158
     159            return GetCurrentState();
     160        }
     161
     162        const double   time = sdata.fElapsedTime*fCounter;
     163        const uint32_t th   = fThreshold;
     164
     165        float data[2+3+1+40+160];
     166        memcpy(data,   &fStartTime, 8);
     167        memcpy(data+2, &th, 4);
     168        data[3] = time;         // total elapsed time
     169        data[4] = fOnTime/time; // relative on time
     170        data[5] = fRate/fCounter;
     171        for (int i=0; i<40; i++)
     172            data[i+6] = fRateBoard[i]/fCounter;
     173        for (int i=0; i<160; i++)
     174            data[i+46] = fRatePatch[i]/fCounter;
     175
     176        ostringstream sout1, sout2, sout3;
     177
     178        sout1 << th << " " << data[5];
     179        for (int i=0; i<200; i++)
     180            sout2 << " " << data[i+6];
     181        sout3 << " " << data[3] << " " << data[4];
     182
     183        Info(sout1.str());
     184
     185        ofstream fout("ratescan.txt", ios::app);
     186        fout << sout1.str() << sout2.str() << sout3.str() << endl;
     187
     188        fDimData.setQuality(fCommand=="FTM_CONTROL/SET_THRESHOLD");
     189        fDimData.setData(data, sizeof(data));
     190        fDimData.Update();
     191
     192        fThreshold += fThresholdStep;
     193
     194        if (fCounter>=fCounterMax)
     195        {
     196            Message("Rate scan stopped due to timeout.");
     197            fThreshold=-1;
     198            return GetCurrentState();
     199        }
     200
     201        if (fThreshold>fThresholdMax)
     202        {
     203            Message("Rate scan finished.");
     204            fThreshold = -1;
     205            return GetCurrentState();
     206        }
     207
     208        // Does this need to be shifted upwards?
     209        if (fCounter>1 && fThresholdStepDyn>0)
     210        {
     211            //const double scale = fCounter/reference/fResolution/fResolution;
     212            //const double step  = floor(scale*fThresholdStepDyn);
     213
     214            fThresholdStep = fCounter*fThresholdStepDyn;
     215        }
     216
     217        //fCounter = -2;  // FIXME: In principle one missed report is enough
     218        fCounter = -1;
     219
     220        const int32_t cmd[2] = { -1, fThreshold };
     221        DimClient::sendCommandNB(fCommand.c_str(), (void*)cmd, 8);
     222
     223        return GetCurrentState();
     224    }
     225
     226    const State GetState(const DimState &s) const
     227    {
     228        return fNetwork.GetState(s.name(), s.state());
     229    }
     230
     231    void PrintState(const DimState &state) const
     232    {
     233        const State rc = GetState(state);
     234
     235        Out() << state.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
     236        Out() << kBold << state.name() << ": ";
     237        if (rc.index==-3)
     238        {
     239            Out() << kReset << "Offline" << endl;
    142240            return;
    143241        }
    144 
    145         if (curr==&fDim)
    146         {
    147             fStatusDim = GetNewState(fDim);
    148             fStatusDim.second = curr->getSize()==4 ? curr->getInt() : 0;
    149             return;
    150         }
    151 
    152         if (curr==&fRates)
    153         {
    154             if (!CheckEventSize(curr->getSize(), "infoHandler[DimTriggerRates]", sizeof(FTM::DimTriggerRates)))
    155                 return;
    156 
    157             if (fThreshold<0/* || fStatusFTM.second!=FTM::kTakingData*/)
    158                 return;
    159 
    160             const FTM::DimTriggerRates &sdata = *static_cast<FTM::DimTriggerRates*>(curr->getData());
    161 
    162             if (++fCounter<0)
    163                 return;
    164 
    165             if (fCounter==0)
    166             {
    167                 fRate = 0;
    168 
    169                 memset(fRateBoard, 0,  40*sizeof(double));
    170                 memset(fRatePatch, 0, 160*sizeof(double));
    171 
    172                 fOnTime = 0;
    173                 return;
    174             }
    175 /*
    176             if (sdata.fTriggerRate==0)
    177             {
    178                 Message("Rate scan stopped due zero trigger rate.");
    179                 fThreshold = -1;
    180                 return;
    181             }
    182 */
    183 
    184             fRate += sdata.fTriggerRate;
    185             for (int i=0; i<40; i++)
    186                 fRateBoard[i] += sdata.fBoardRate[i];
    187             for (int i=0; i<160; i++)
    188                 fRatePatch[i] += sdata.fPatchRate[i];
    189 
    190             double reference = fRate;
    191             if (fReference==kBoard)
    192                 reference = fRateBoard[fReferenceIdx];
    193             if (fReference==kPatch)
    194                 reference = fRatePatch[fReferenceIdx];
    195 
    196             fOnTime += sdata.fOnTime;
    197 
    198             reference *= sdata.fElapsedTime;
    199 
    200             if ((reference==0 || sqrt(reference)>fResolution*reference) && fCounter<fCounterMax)
    201             {
    202                 ostringstream out;
    203                 out << "Triggers so far: " << reference;
    204                 if (reference>0)
    205                     out << " (" << sqrt(reference)/reference << ")";
    206                 Info(out);
    207 
    208                 return;
    209             }
    210 
    211             const double   time = sdata.fElapsedTime*fCounter;
    212             const uint32_t th   = fThreshold;
    213 
    214             float data[2+3+1+40+160];
    215             memcpy(data,   &fStartTime, 8);
    216             memcpy(data+2, &th, 4);
    217             data[3] = time;         // total elapsed time
    218             data[4] = fOnTime/time; // relative on time
    219             data[5] = fRate/fCounter;
    220             for (int i=0; i<40; i++)
    221                 data[i+6] = fRateBoard[i]/fCounter;
    222             for (int i=0; i<160; i++)
    223                 data[i+46] = fRatePatch[i]/fCounter;
    224 
    225             ostringstream sout1, sout2, sout3;
    226 
    227             sout1 << th << " " << data[5];
    228             for (int i=0; i<200; i++)
    229                 sout2 << " " << data[i+6];
    230             sout3 << " " << data[3] << " " << data[4];
    231 
    232             Info(sout1.str());
    233 
    234             ofstream fout("ratescan.txt", ios::app);
    235             fout << sout1.str() << sout2.str() << sout3.str() << endl;
    236 
    237             fDimData.setQuality(fCommand=="FTM_CONTROL/SET_THRESHOLD");
    238             fDimData.setData(data, sizeof(data));
    239             fDimData.Update();
    240 
    241             fThreshold += fThresholdStep;
    242 
    243             if (fCounter>=fCounterMax)
    244             {
    245                 Message("Rate scan stopped due to timeout.");
    246                 fThreshold=-1;
    247                 return;
    248             }
    249 
    250             if (fThreshold>fThresholdMax)
    251             {
    252                 Message("Rate scan finished.");
    253                 fThreshold = -1;
    254                 return;
    255             }
    256 
    257             // Does this need to be shifted upwards?
    258             if (fCounter>1 && fThresholdStepDyn>0)
    259             {
    260                 //const double scale = fCounter/reference/fResolution/fResolution;
    261                 //const double step  = floor(scale*fThresholdStepDyn);
    262 
    263                 fThresholdStep = fCounter*fThresholdStepDyn;
    264             }
    265 
    266             //fCounter = -2;  // FIXME: In principle one missed report is enough
    267             fCounter = -1;
    268 
    269             const int32_t cmd[2] = { -1, fThreshold };
    270             DimClient::sendCommandNB(fCommand.c_str(), (void*)cmd, 8);
    271         }
    272     }
    273 
    274     void PrintState(const pair<Time,int> &state, const char *server)
    275     {
    276         const State rc = fNetwork.GetState(server, state.second);
    277 
    278         Out() << state.first.GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
    279         Out() << kBold << server << ": ";
    280         Out() << rc.name << "[" << rc.index << "]";
     242        if (rc.index==-2)
     243            Out() << state.state();
     244        else
     245            Out() << rc.name << "[" << rc.index << "]";
    281246        Out() << kReset << " - " << kBlue << rc.comment << endl;
    282247    }
    283248
    284     int Print()
    285     {
    286         Out() << fStatusDim.first.GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
    287         Out() << kBold << "DIM_DNS: ";
    288         if (fStatusDim.second==0)
    289             Out() << "Offline" << endl;
    290         else
    291             Out() << "V" << fStatusDim.second/100 << 'r' << fStatusDim.second%100 << endl;
    292 
    293         PrintState(fStatusFTM,  "FTM_CONTROL");
     249    int Print() const
     250    {
     251        Out() << fDim.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
     252        Out() << kBold << "DIM_DNS: " << fDim.version() << endl;
     253
     254        PrintState(fDimFTM);
    294255
    295256        return GetCurrentState();
     
    298259    int StartRateScan(const EventImp &evt, const string &command)
    299260    {
    300         if (!CheckEventSize(evt.GetSize(), "StartRateScan", 12))
     261        if (!CheckEventSize(evt, 12))
    301262            return kSM_FatalError;
    302263
     
    355316        Message("Rate scan manually stopped.");
    356317
    357         //if (fStatusFTM.second==FTM::kTakingData)
     318        //if (fDimFTM.state()==FTM::kTakingData)
    358319        {
    359320            //Message("Stopping FTM");
     
    373334    int SetReferenceBoard(const EventImp &evt)
    374335    {
    375         if (!CheckEventSize(evt.GetSize(), "SetReferenceBoard", 4))
     336        if (!CheckEventSize(evt, 4))
    376337            return kSM_FatalError;
    377338
     
    390351    int SetReferencePatch(const EventImp &evt)
    391352    {
    392         if (!CheckEventSize(evt.GetSize(), "SetReferencePatch", 4))
     353        if (!CheckEventSize(evt, 4))
    393354            return kSM_FatalError;
    394355
     
    407368    int ChangeStepSize(const EventImp &evt)
    408369    {
    409         if (!CheckEventSize(evt.GetSize(), "ChangeStepSize", 4))
     370        if (!CheckEventSize(evt, 4))
    410371            return kSM_FatalError;
    411372
     
    423384    int ChangeMaximum(const EventImp &evt)
    424385    {
    425         if (!CheckEventSize(evt.GetSize(), "ChangeMaximum", 4))
     386        if (!CheckEventSize(evt, 4))
    426387            return kSM_FatalError;
    427388
     
    440401        //poll_one();
    441402
    442         if (fStatusDim.second==0)
     403        if (!fDim.online())
    443404            return kStateDimNetworkNA;
    444405
    445406        // All subsystems are not connected
    446         if (fStatusFTM.second<FTM::kConnected)
     407        if (fDimFTM.state()<FTM::kConnected)
    447408            return kStateDisconnected;
    448409
    449410        // At least one subsystem is not connected
    450         //        if (fStatusFTM.second>=FTM::kConnected)
     411        //        if (fDimFTM.state()>=FTM::kConnected)
    451412        return fThreshold<0 ? kStateConnected : kStateInProgress;
    452413    }
     
    454415public:
    455416    StateMachineRateScan(ostream &out=cout) : StateMachineDim(out, "RATE_SCAN"),
    456         fStatusDim(make_pair(Time(), -2)),
    457         fStatusFTM(make_pair(Time(), -2)),
    458         fDim("DIS_DNS/VERSION_NUMBER",  (void*)NULL, 0, this),
    459         fFTM("FTM_CONTROL/STATE",       (void*)NULL, 0, this),
    460         fRates("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
     417        fDimFTM("FTM_CONTROL"),
    461418        fDimData("RATE_SCAN/DATA", "X:1;I:1;F:1;F:1;F:1;F:40;F:160",
    462419                 "|Id[s]:Start time used to identify measurement (UnixTime)"
     
    480437        // previous state but this might introduce some overhead of
    481438        // deletion and creation of threads and more.
     439
     440        fDim.Subscribe(*this);
     441        fDimFTM.Subscribe(*this);
     442
     443        Subscribe("FTM_CONTROL/TRIGGER_RATES")
     444            (bind(&StateMachineRateScan::HandleTriggerRates, this, placeholders::_1));
    482445
    483446        // State names
Note: See TracChangeset for help on using the changeset viewer.