-static char *rcsId = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/evtbuild.c,v 6.27 2001-04-12 12:36:30 hades Exp $";
+static char *rcsId = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/evtbuild.c,v 6.28 2001-04-26 11:59:49 hades Exp $";
#define _POSIX_C_SOURCE 199309L
#include "shmtrans.h"
#include "ansiTape.h"
+#define NTRIGTYPES 16
+
+static time_t ourTime;
+
typedef struct TheArgsS {
unsigned long nrOfMsgs;
+ unsigned long skipMsgs[NTRIGTYPES];
char outPath[PARAM_MAX_VALUE_LEN];
char outDev[PARAM_MAX_VALUE_LEN];
unsigned long runNr;
static void usage(const char *progName)
{
msglog(LOG_ERR, "Usage: %s [-x expId]\n", progName);
- msglog(LOG_ERR, "Usage: [-m nrOfMsgs] [-r runNr]\n");
+ msglog(LOG_ERR, "Usage: [-m nrOfMsgs] [-t skipMsgs ...] [-r runNr]\n");
msglog(LOG_ERR, "Usage: [-f slowCtrlFile ...] [-o outPath] [-d null|tape|file]\n");
msglog(LOG_ERR, "Usage: [-a (agent)] [-p priority]\n");
msglog_usage();
int i;
msglog(LOG_DEBUG, "nrOfMsgs: %d\n", my->nrOfMsgs);
+ for (i = 0; i < NTRIGTYPES; i++) {
+ msglog(LOG_DEBUG, "skipMsgs[%d]: 0x%08x\n", i, my->skipMsgs[i]);
+ }
for (i = 0; i < my->slowCtrlFileCnt; i++) {
msglog(LOG_DEBUG, "slowCtrlFiles[%d]: %s\n", i, my->slowCtrlFiles[i]);
}
int i;
my->nrOfMsgs = 0;
+ for (i = 0; i < NTRIGTYPES; i++) {
+ my->skipMsgs[i] = 0;
+ }
for (i = 0; i < PARAM_MAX_ARRAY_LEN; i++) {
my->slowCtrlFiles[i] = my->slowCtrlFilesS[i];
}
my->slowCtrlFileCnt = 0;
strcpy(my->outPath, "");
strcpy(my->outDev, "null");
- my->runNr = time(NULL);
+ my->runNr = ourTime;
strcpy(my->expId, "xx");
my->priority = 0;
my->isStandalone = 1;
static int argsFromCL(TheArgs *my, int argc, char *argv[]) {
int i;
+ int trigType = 0;
- while ((i = getopt(argc, argv, "am:f:s:r:o:d:q:p:v:x:")) != -1) {
+ while ((i = getopt(argc, argv, "am:t:f:s:r:o:d:q:p:v:x:")) != -1) {
switch (i) {
case 'm':
- my->nrOfMsgs = atoi(optarg);
+ my->nrOfMsgs = strtoul(optarg, NULL, 0);
+ break;
+ case 't':
+ my->skipMsgs[trigType++] = strtoul(optarg, NULL, 0);
break;
case 'f':
strcpy(my->slowCtrlFiles[my->slowCtrlFileCnt++], optarg);
break;
case 'r':
- my->runNr = atoi(optarg);
+ my->runNr = strtoul(optarg, NULL, 0);
break;
case 's':
msglog(LOG_WARNING,
my->isStandalone = 0;
break;
case 'p':
- my->priority = atoi(optarg);
+ my->priority = strtoul(optarg, NULL, 0);
break;
case 'q':
- my->queueSize = atoi(optarg);
+ my->queueSize = strtoul(optarg, NULL, 0);
break;
case 'v':
strcpy(my->verbosity, optarg);
conParam(param);
Param_getInt(param, argv[0], "nrofmsgs", ¶mWasFound, &my->nrOfMsgs);
+ Param_getIntArray(param, argv[0], "skipmsgs",
+ NTRIGTYPES, ¶mWasFound, my->skipMsgs);
Param_getStringArray(param, argv[0], "slwctrlfile",
PARAM_MAX_ARRAY_LEN, &my->slowCtrlFileCnt, my->slowCtrlFiles);
Param_getString(param, argv[0], "outpath", ¶mWasFound, my->outPath);
desParam(param);
}
+
+static void storeRunInfoStart(const char *name, time_t t, const char *expId, unsigned long runId, const char* fileName) {
+ Param paramS, *param = ¶mS;
+ int paramWasFound;
+ char s[20];
+
+ conParam(param);
+ strftime(s, 20, "%Y-%m-%dT%H:%M:%S", localtime(&t));
+ Param_storeString(param, name, "start_date", s);
+ Param_storeString(param, name, "exp_id", expId);
+ Param_storeInt(param, name, "run_id", runId);
+ Param_storeString(param, name, "file_name", fileName);
+ desParam(param);
+}
+
+static void storeRunInfoStop(const char *name, time_t t, unsigned long evtsComplete, unsigned long bytesWritten) {
+ Param paramS, *param = ¶mS;
+ int paramWasFound;
+ char s[20];
+
+ conParam(param);
+ strftime(s, 20, "%Y-%m-%dT%H:%M:%S", localtime(&t));
+ Param_storeString(param, name, "stop_date", s);
+ Param_storeInt(param, name, "evts_complete", evtsComplete);
+ Param_storeInt(param, name, "bytes_written", bytesWritten);
+ desParam(param);
+}
+
/* BUGBUG bailOut not proper yet */
int main(int argc, char *argv[])
{
char fileName[_POSIX_PATH_MAX];
FILE *outFile;
AnsiTape *outTape;
- unsigned long nrOfSubEvts;
void *evt;
void *subEvt;
int scanWasSuccessful;
- int currNrOfSubEvts;
UInt4 currTrigNr;
+ UInt4 currId;
unsigned long *evtsDiscarded;
unsigned long *evtsComplete;
unsigned long *bytesWritten;
+ ourTime = time(NULL);
+
msglog_setlevel(argv[0], "info");
argsDefault(theArgs);
/* construct a default filename */
strcpy(fileName, theArgs->expId);
- strftime(fileName + strlen(fileName), 18, "%y%j%H%M%S.hld", localtime(&theArgs->runNr));
+ strftime(fileName + strlen(fileName), 18, "%y%j%H%M%S.hld", localtime(&ourTime));
/* construct the output path */
if (strcmp(theArgs->outPath, "") == 0) {
bytesWritten = Worker_addStatistic(worker, "bytesWritten");
Worker_initEnd(worker);
+ storeRunInfoStart(argv[0], ourTime, theArgs->expId, theArgs->runNr, fileName);
evt = newEvt(EvtDecoding_64bitAligned, EvtId_runStart, theArgs->runNr, theArgs->expId);
for (i = 0; i < theArgs->slowCtrlFileCnt; i++) {
evt = appendFile(evt, theArgs->slowCtrlFiles[i]);
}
deleteEvt(evt);
- nrOfSubEvts = theArgs->nrOfMsgs;
- currTrigNr = 0xffffffff;
+ currId = 0;
while (setjmp(terminateJmp) == 0) {
- int tryNext;
+ int step;
+ int evtIsBroken = 0;
Worker_dump(worker, 1);
-
- i = 0;
- tryNext = 0;
+#ifndef NDEBUG
+ msglog(LOG_DEBUG, "evtsComplete: %d, evtsDiscarded %d\n", *evtsComplete, *evtsDiscarded);
+#endif
evt = newEvt(EvtDecoding_64bitAligned, EvtId_data, theArgs->runNr, theArgs->expId);
- currNrOfSubEvts = 0;
- while (i < theArgs->nrOfMsgs) {
- if (hadTuQueue[i] == NULL) {
- void *storage;
-
- storage = ShmTrans_recv(shmTrans[i]);
- hadTuQueue[i] = allocMem(HadTuQueue_sizeOf());
- conHadTuQueue_voidP(hadTuQueue[i], storage);
- }
- if (NULL != (subEvt = HadTuQueue_front(hadTuQueue[i]))) {
+ for (i = 0; i < theArgs->nrOfMsgs && !evtIsBroken; i += step) {
+ if (theArgs->skipMsgs[currId] & (1 << i)) {
+ step = 1;
+ } else {
+ if (hadTuQueue[i] == NULL) {
+ void *storage;
+
+ storage = ShmTrans_recv(shmTrans[i]);
+ hadTuQueue[i] = allocMem(HadTuQueue_sizeOf());
+ conHadTuQueue_voidP(hadTuQueue[i], storage);
+ }
+ subEvt = HadTuQueue_front(hadTuQueue[i]);
#ifndef NDEBUG
msglog(LOG_DEBUG, "hadTuQueue[%d]: %p = subEvt: %s\n", i, subEvt, SubEvt_2charP(subEvt));
- msglog(LOG_DEBUG, "currTrigNr: 0x%08x, currNrOfSubEvts %d\n", currTrigNr, currNrOfSubEvts);
- msglog(LOG_DEBUG, "evtsComplete: %d, evtsDiscarded %d\n", *evtsComplete, *evtsDiscarded);
-#endif
- if (i == 0 && currNrOfSubEvts == 0) {
-#if 0
- if (currTrigNr != 0xffffffff) {
- /* upper 24 bit of trigNr should be a sequence */
- (*evtsDiscarded) += (SubEvt_trigNr(subEvt) >> 8)
- - ((currTrigNr + 0x100) >> 8);
- }
#endif
+ if (i == 0) {
currTrigNr = SubEvt_trigNr(subEvt);
+ currId = SubEvt_id(subEvt);
+#ifndef NDEBUG
+ msglog(LOG_DEBUG, "currTrigNr: 0x%08x, currId 0x%08x\n", currTrigNr, currId);
+#endif
}
if (SubEvt_trigNr(subEvt) == currTrigNr) {
evt = Evt_appendSubEvt(evt, subEvt);
HadTuQueue_pop(hadTuQueue[i]);
- currNrOfSubEvts++;
+ step = 1;
} else if (SubEvt_trigNr(subEvt) < currTrigNr) {
- HadTuQueue_pop(hadTuQueue[i]);
/* BUGBUG subevt discarded, not in statistic */
+ HadTuQueue_pop(hadTuQueue[i]);
+ step = 0;
} else {
- tryNext = 1;
+ evtIsBroken = 1;
+ }
+ if (HadTuQueue_empty(hadTuQueue[i])) {
+ desHadTuQueue(hadTuQueue[i]);
+ freeMem(hadTuQueue[i]);
+ hadTuQueue[i] = NULL;
+ ShmTrans_free(shmTrans[i]);
}
- }
- if (HadTuQueue_empty(hadTuQueue[i])) {
- desHadTuQueue(hadTuQueue[i]);
- freeMem(hadTuQueue[i]);
- hadTuQueue[i] = NULL;
- ShmTrans_free(shmTrans[i]);
- }
- if (tryNext) {
- i++;
- tryNext = 0;
}
}
- if (currNrOfSubEvts == nrOfSubEvts) {
+ if (!evtIsBroken) {
if (outFile != NULL) {
fwrite(evt, 1, Evt_paddedSize(evt), outFile);
} else if (outTape != NULL) {
}
Worker_dump(worker, 0);
+ ourTime = time(NULL);
+ storeRunInfoStop(argv[0], ourTime, *evtsComplete, *bytesWritten);
+
+
evt = newEvt(EvtDecoding_64bitAligned, EvtId_runStop, theArgs->runNr, theArgs->expId);
for (i = 0; i < theArgs->slowCtrlFileCnt; i++) {
evt = appendFile(evt, theArgs->slowCtrlFiles[i]);
-agent create hades05 hades /home/hades/tt00/eb/hadaq
-agent create r2-26 hades /hades/usr/hades/tt00/rich/hadaq
-agent create r2-25 hades /hades/usr/hades/tt00/trig/hadaq
-worker create hades05:evtbuild -a -p -2 -s 5 -m 2
-worker create hades05:netmem -a -p -1 -m 2 -i ATM:0:50 -i ATM:0:51
-worker create r2-26:memnet -a -p -1 -w 68000 -o ATM:0:50
-worker create r2-26:readout -a -p -2
-worker create r2-25:memnet -a -p -1 -w 68000 -o ATM:0:51
-worker create r2-25:readout -a -p -2
+agent create hadeb01 hades /home/hades/mar01/eb/hadaq
+agent create r2-24 hades /hades/usr/hades/mar01/rich/hadaq
+agent create r2-27 hades /hades/usr/hades/mar01/rich/hadaq
+agent create r2-28 hades /hades/usr/hades/mar01/rich/hadaq
+agent create r2-29 hades /hades/usr/hades/mar01/trig/hadaq
+worker create hadeb01:evtbuild -a -p -2 -m 4
+worker create hadeb01:netmem -a -p -1 -m 4 -i ATM:0:50 -i ATM:0:51 -i ATM:0:52 -i ATM:0:53
+worker create r2-24:memnet -a -p -1 -w 0 -o ATM:0:50
+worker create r2-24:readout -a -p -2
+worker create r2-27:memnet -a -p -1 -w 0 -o ATM:0:51
+worker create r2-27:readout -a -p -2
+worker create r2-28:memnet -a -p -1 -w 0 -o ATM:0:52
+worker create r2-28:readout -a -p -2
+worker create r2-29:memnet -a -p -1 -w 0 -o ATM:0:53
+worker create r2-29:readout -a -p -2
group create acquisition
group create run
-group add acquisition r2-26:memnet
-group add acquisition r2-26:readout
-group add acquisition r2-25:memnet
-group add acquisition r2-25:readout
-group add run hades05:evtbuild
-group add run hades05:netmem
+group add acquisition r2-24:memnet
+group add acquisition r2-24:readout
+group add acquisition r2-27:memnet
+group add acquisition r2-27:readout
+group add acquisition r2-28:memnet
+group add acquisition r2-28:readout
+group add acquisition r2-29:memnet
+group add acquisition r2-29:readout
+group add run hadeb01:evtbuild
+group add run hadeb01:netmem
set duringInit {
- {rsh r2-26 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; cd tt00/slow; ./rich init'} </dev/null }
- {rsh r2-25 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; cd tt00/slow; ./trig init'} </dev/null }
+ {rsh r2-24 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich0 init'} </dev/null }
+ {rsh r2-27 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich2 init'} </dev/null }
+ {rsh r2-28 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich2ipu init'} </dev/null }
+ {rsh e7_25 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof1 init'} </dev/null >>&hadaq.log}
+ {rsh e7_21 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof2 init'} </dev/null >>&hadaq.log}
+ {rsh e7_41 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof3 init'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc init'} </dev/null }
}
set beforeStartAcq {
- {rsh r2-26 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; cd tt00/slow; ./rich reset'} </dev/null >>&hadaq.log}
- {rsh r2-25 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; cd tt00/slow; ./trig reset'} </dev/null >>&hadaq.log}
- {rsh r2-26 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; cd tt00/slow; ./rich start'} </dev/null >>&hadaq.log}
- {rsh r2-25 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; cd tt00/slow; ./trig start'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc reset'} </dev/null >>&hadaq.log}
+ {rsh r2-24 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich0 reset'} </dev/null }
+ {rsh r2-27 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich2 reset'} </dev/null }
+ {rsh r2-28 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich2ipu reset'} </dev/null }
+ {rsh e7_25 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof1 reset'} </dev/null >>&hadaq.log}
+ {rsh e7_21 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof2 reset'} </dev/null >>&hadaq.log}
+ {rsh e7_41 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof3 reset'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc reset'} </dev/null >>&hadaq.log}
+ {rsh r2-24 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich0 start'} </dev/null }
+ {rsh r2-27 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich2 start'} </dev/null }
+ {rsh r2-28 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich2ipu start'} </dev/null }
+ {rsh e7_25 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof1 start'} </dev/null >>&hadaq.log}
+ {rsh e7_21 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof2 start'} </dev/null >>&hadaq.log}
+ {rsh e7_41 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./tof3 start'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc start'} </dev/null >>&hadaq.log}
}
set afterStartAcq {
- {rsh r2-25 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; dtuctrl -t ctu start'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./ctustart'} </dev/null >>&hadaq.log}
}
set beforeStopAcq {
- {rsh r2-25 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; dtuctrl -t ctu stop'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./ctustop'} </dev/null >>&hadaq.log}
}
set afterStopAcq {
- {rsh r2-26 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; cd tt00/slow; ./rich stop'} </dev/null >>&hadaq.log}
- {rsh r2-25 sh -c {'PATH=$PATH:$HOME/bin/POWERPC_LYNXOS_2_5_1; cd tt00/slow; ./trig stop'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc stop'} </dev/null >>&hadaq.log}
+ {rsh r2-24 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich0 stop'} </dev/null }
+ {rsh r2-27 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich2 stop'} </dev/null }
+ {rsh r2-28 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./rich2ipu stop'} </dev/null }
}
-agent create hades24 hades /home/hades/nov00/eb/hadaq
-agent create r2-14 hades /hades/usr/hades/nov00/shw/hadaq
-agent create r2-13 hades /hades/usr/hades/nov00/trig/hadaq
-worker create hades24:evtbuild -a -p -2 -s 2 -m 2
-worker create hades24:netmem -a -p -1 -m 2 -i ATM:0:100 -i ATM:0:101
-worker create r2-14:memnet -a -p -1 -w 68000 -o ATM:0:100
-worker create r2-14:readout -a -p -2
-worker create r2-13:memnet -a -p -1 -w 68000 -o ATM:0:101
-worker create r2-13:readout -a -p -2
+agent create hadeb01 hades /home/hades/mar01/eb/hadaq
+agent create r2-14 hades /hades/usr/hades/mar01/shw/hadaq
+agent create r2-29 hades /hades/usr/hades/mar01/trig/hadaq
+worker create hadeb01:evtbuild -a -p -2 -m 2
+worker create hadeb01:netmem -a -p -1 -m 2 -i ATM:0:50 -i ATM:0:51
+worker create r2-14:memnet -a -p -1 -w 0 -o ATM:0:50
+worker create r2-14:readout -a -p -2 -w 0
+worker create r2-29:memnet -a -p -1 -w 0 -o ATM:0:51
+worker create r2-29:readout -a -p -2 -w 0
group create acquisition
group create run
group add acquisition r2-14:memnet
group add acquisition r2-14:readout
-group add acquisition r2-13:memnet
-group add acquisition r2-13:readout
-group add run hades24:evtbuild
-group add run hades24:netmem
+group add acquisition r2-29:memnet
+group add acquisition r2-29:readout
+group add run hadeb01:evtbuild
+group add run hadeb01:netmem
set duringInit {
- {rsh r2-14 sh -c {'. .bash_profile; cd nov00/slow; ./shw init'} </dev/null }
- {rsh r2-13 sh -c {'. .bash_profile; cd nov00/slow; ./trig init'} </dev/null }
+ {rsh r2-14 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./shw init'} </dev/null }
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc init'} </dev/null }
}
set beforeStartAcq {
- {rsh r2-13 sh -c {'. .bash_profile; cd nov00/slow; ./trig reset'} </dev/null >>&hadaq.log}
- {rsh r2-14 sh -c {'. .bash_profile; cd nov00/slow; ./shw reset'} </dev/null >>&hadaq.log}
- {rsh r2-14 sh -c {'. .bash_profile; cd nov00/slow; ./shw start'} </dev/null >>&hadaq.log}
- {rsh r2-13 sh -c {'. .bash_profile; cd nov00/slow; ./trig start'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc reset'} </dev/null >>&hadaq.log}
+ {rsh r2-14 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./shw reset'} </dev/null }
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc reset'} </dev/null >>&hadaq.log}
+ {rsh r2-14 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./shw start'} </dev/null }
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc start'} </dev/null >>&hadaq.log}
}
set afterStartAcq {
- {rsh r2-13 sh -c {'. .bash_profile; ctustart'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./ctustart'} </dev/null >>&hadaq.log}
}
set beforeStopAcq {
- {rsh r2-13 sh -c {'. .bash_profile; ctustop'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./ctustop'} </dev/null >>&hadaq.log}
}
set afterStopAcq {
- {rsh r2-14 sh -c {'. .bash_profile; cd nov00/slow; ./shw stop'} </dev/null >>&hadaq.log}
- {rsh r2-13 sh -c {'. .bash_profile; cd nov00/slow; ./trig stop'} </dev/null >>&hadaq.log}
+ {rsh r2-29 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./trigconc stop'} </dev/null >>&hadaq.log}
+ {rsh r2-14 sh -c {'. bin/daqenv mar01; cd mar01/slow; ./shw stop'} </dev/null }
}