Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Instrument Control
NomadSpecialModules
Commits
732afa8f
Commit
732afa8f
authored
Mar 13, 2020
by
yannick legoc
Browse files
Starting with mantid reduction
parent
dda6a36c
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/controllers/mantidreduction/.gitignore
0 → 100644
View file @
732afa8f
/RequestMessages.pb.cc
/RequestMessages.pb.h
src/controllers/mantidreduction/Module.xml
0 → 100644
View file @
732afa8f
<module
name=
"mantidreduction"
>
<controller
class=
"mantid::ReductionController"
/>
<include
path=
"$(NOMAD_HOME)/../NomadModules/src"
/>
<script
exec=
"protoc --cpp_out=. RequestMessages.proto"
/>
</module>
src/controllers/mantidreduction/ReductionController.cpp
0 → 100644
View file @
732afa8f
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "ReductionController.h"
#include "controllers/common/family/Families.h"
#include "InstrumentManager/InstrumentManager.h"
#include "RequestMessages.pb.h"
#include <boost/lexical_cast.hpp>
#include <common/base/Date.h>
#include <fstream>
#include <iostream>
#include <nexus/napi.h>
namespace
mantid
{
using
namespace
std
;
using
namespace
common
;
using
namespace
boost
;
using
namespace
cameo
;
const
std
::
string
ReductionController
::
TYPE
=
"mantid_reduction"
;
const
std
::
string
ReductionController
::
REMOTE_APPLICATION
=
"madmanserver"
;
const
std
::
string
ReductionController
::
RESPONDER
=
"responder"
;
const
std
::
string
ReductionController
::
PUBLISHER
=
"publisher"
;
const
std
::
string
ReductionController
::
PROCESSED_FILE
=
"processed.nxs"
;
ReductionController
::
ReductionController
(
const
std
::
string
&
name
)
:
ExperimentController
(
name
)
{
setFamily
(
family
::
ACQUISITION
,
family
::
COUNT
);
serverEndpoint
.
init
(
this
,
SAVE
,
"cameo_server"
);
initialized
.
init
(
this
,
NOSAVE
,
"initialized"
);
fileDirectory
.
init
(
this
,
SAVE
,
"file_directory"
);
filename
.
init
(
this
,
SAVE
,
"filename"
);
x
.
init
(
this
,
NOSAVE
,
"x"
);
data
.
init
(
this
,
NOSAVE
,
"data"
);
}
ReductionController
::
ReductionController
(
const
ReductionController
&
controller
)
:
ExperimentController
(
controller
)
{
}
ReductionController
::~
ReductionController
()
{
if
(
m_subscriberThread
.
get
()
!=
nullptr
)
{
m_subscriber
->
cancel
();
m_subscriberThread
->
join
();
}
if
(
m_remoteApplication
.
get
()
!=
nullptr
)
{
// Stop the remote application.
m_remoteApplication
->
stop
();
// Wait for the termination
application
::
State
state
=
m_remoteApplication
->
waitFor
();
cout
<<
"Remote application "
<<
m_remoteApplication
->
getName
()
<<
" terminated with state "
<<
application
::
toString
(
state
)
<<
endl
;
}
}
void
ReductionController
::
postConfiguration
()
{
if
(
serverEndpoint
()
==
""
)
{
m_server
.
reset
(
new
Server
(
application
::
This
::
getServer
().
getEndpoint
()));
}
else
{
m_server
.
reset
(
new
Server
(
serverEndpoint
()));
}
initialized
=
initApplication
();
registerControllers
();
for
(
uint32
i
=
0
;
i
<
m_scanControllers
.
size
();
++
i
)
{
registerUpdater
(
m_scanControllers
[
i
]
->
serializerEvent
,
&
ReductionController
::
updateScanSerializerEvent
,
this
,
i
);
}
}
void
ReductionController
::
registerControllers
()
{
map
<
string
,
ExperimentController
*>
experimentControllersMap
=
InstrumentManager
::
getInstance
()
->
getAllInstalledExperimentControllersMap
();
map
<
string
,
ExperimentController
*>::
iterator
it
;
for
(
it
=
experimentControllersMap
.
begin
();
it
!=
experimentControllersMap
.
end
();
it
++
)
{
if
(
dynamic_cast
<
scan
::
GenericScan1D
*>
(
it
->
second
)
!=
0
)
{
scan
::
GenericScan1D
*
scan1D
=
dynamic_cast
<
scan
::
GenericScan1D
*>
(
it
->
second
);
scan1D
->
attach
(
this
);
//Attach it in order to be able to receive propertyChange events
m_scanControllers
.
push_back
(
scan1D
);
cout
<<
"Attached "
<<
scan1D
->
getName
()
<<
endl
;
}
}
}
void
ReductionController
::
updateScanSerializerEvent
(
int32
i
)
{
if
(
m_scanControllers
[
i
]
->
serializerEvent
()
==
true
)
{
cout
<<
"Scan numor "
<<
m_scanControllers
[
i
]
->
numor
()
<<
endl
;
}
}
bool
ReductionController
::
initApplication
()
{
// Do not initialize if it is already done
if
(
initialized
())
{
return
true
;
}
// Start the remote server
if
(
!
m_server
->
isAvailable
(
1000
))
{
cout
<<
"Remote server is not available"
<<
endl
;
return
false
;
}
cout
<<
"Remote server is connected"
<<
endl
;
m_remoteApplication
=
m_server
->
connect
(
REMOTE_APPLICATION
);
if
(
m_remoteApplication
->
exists
())
{
// The application exists from a previous server session
m_remoteApplication
->
kill
();
application
::
State
state
=
m_remoteApplication
->
waitFor
();
cout
<<
"Terminated remote application with state "
<<
application
::
toString
(
state
)
<<
endl
;
}
m_remoteApplication
=
m_server
->
start
(
REMOTE_APPLICATION
);
if
(
!
m_remoteApplication
->
exists
())
{
cout
<<
"No remote application"
<<
endl
;
return
false
;
}
// Create the requester
m_requester
=
application
::
Requester
::
create
(
*
m_remoteApplication
,
RESPONDER
);
if
(
m_requester
.
get
()
==
0
)
{
cout
<<
"requester error"
<<
endl
;
return
false
;
}
// Create the subscriber.
m_subscriber
=
application
::
Subscriber
::
create
(
*
m_remoteApplication
,
"publisher"
);
m_subscriberThread
.
reset
(
new
std
::
thread
([
this
]
{
string
result
;
while
(
m_subscriber
->
receiveBinary
(
result
))
{
// Parse the response.
madman
::
Result
fileResult
;
fileResult
.
ParseFromString
(
result
);
// Write the file to disk.
writeFile
(
PROCESSED_FILE
,
fileResult
.
content
());
// Read the file.
readProcessedFile
();
// Remove the file.
remove
(
PROCESSED_FILE
.
c_str
());
cout
<<
"Result size "
<<
fileResult
.
content
().
size
()
<<
endl
;
}
}));
// Application initialized
initialized
=
true
;
return
true
;
}
void
ReductionController
::
readFile
(
const
std
::
string
&
nexusFileName
,
std
::
string
&
fileContent
)
{
streampos
size
;
ifstream
file
(
nexusFileName
.
c_str
(),
ios
::
in
|
ios
::
binary
|
ios
::
ate
);
if
(
file
.
is_open
())
{
size
=
file
.
tellg
();
// Reserve the string.
fileContent
.
resize
(
size
);
// Get the allocated array.
char
*
array
=
(
char
*
)
fileContent
.
data
();
file
.
seekg
(
0
,
ios
::
beg
);
file
.
read
(
array
,
size
);
file
.
close
();
}
else
{
cerr
<<
"File "
<<
nexusFileName
<<
" cannot be read."
<<
endl
;
}
}
void
ReductionController
::
writeFile
(
const
std
::
string
&
nexusFileName
,
const
std
::
string
&
fileContent
)
{
ofstream
file
;
file
.
open
(
nexusFileName
,
ios
::
binary
);
file
<<
fileContent
;
file
.
close
();
}
void
ReductionController
::
readProcessedFile
()
{
NXhandle
fileId
;
// Open the file.
int
res
=
NXopen
(
PROCESSED_FILE
.
c_str
(),
NXACC_RDWR
,
&
fileId
);
if
(
res
!=
NX_OK
)
{
cerr
<<
"Cannot open processed.nxs."
<<
endl
;
return
;
}
res
=
NXopengroup
(
fileId
,
"mantid_workspace_1"
,
"NXentry"
);
if
(
res
!=
NX_OK
)
{
cerr
<<
"Cannot open group mantid_workspace_1."
<<
endl
;
return
;
}
res
=
NXopengroup
(
fileId
,
"workspace"
,
"NXdata"
);
if
(
res
!=
NX_OK
)
{
cerr
<<
"Cannot open group workspace"
<<
endl
;
return
;
}
// Read X data.
int
rank
=
1
;
int
dims
[
2
];
int
dataType
;
NXopendata
(
fileId
,
"axis1"
);
NXgetinfo
(
fileId
,
&
rank
,
dims
,
&
dataType
);
if
(
dataType
!=
NX_FLOAT64
)
{
cerr
<<
"Problem with the type of data of axis1."
<<
endl
;
return
;
}
int
xSize
=
dims
[
0
];
delete
[]
x
.
get
();
double
*
xData
=
new
double
[
xSize
];
NXgetdata
(
fileId
,
xData
);
x
.
set
(
xData
);
// We set the size - 1 to have the same size than the data.
x
.
setSize
(
xSize
-
1
);
// Close the data.
NXclosedata
(
fileId
);
// Read values data.
rank
=
2
;
NXopendata
(
fileId
,
"values"
);
NXgetinfo
(
fileId
,
&
rank
,
dims
,
&
dataType
);
if
(
dataType
!=
NX_FLOAT64
)
{
cerr
<<
"Problem with the type of data of values."
<<
endl
;
return
;
}
if
(
dims
[
1
]
+
1
!=
xSize
)
{
cerr
<<
"Problem with the size "
<<
dims
[
1
]
<<
" of values."
<<
endl
;
return
;
}
int
dataSize
=
dims
[
1
];
delete
[]
data
.
get
();
double
*
values
=
new
double
[
dataSize
];
NXgetdata
(
fileId
,
values
);
data
.
set
(
values
);
data
.
setSize
(
dataSize
);
NXclosedata
(
fileId
);
NXclosegroup
(
fileId
);
NXclosegroup
(
fileId
);
NXclose
(
&
fileId
);
cout
<<
"Data size "
<<
dataSize
<<
endl
;
// Check the data.
int
index
=
0
;
while
(
index
<
dataSize
)
{
if
(
!
isfinite
(
values
[
index
]))
{
break
;
}
++
index
;
}
cout
<<
"Forced size to "
<<
index
<<
endl
;
x
.
setSize
(
index
);
data
.
setSize
(
index
);
/* int fixedSize = 280;
x.setSize(index < fixedSize ? index : fixedSize);
data.setSize(index < fixedSize ? index : fixedSize);*/
x
.
sendEvent
();
data
.
sendEvent
();
cout
<<
"Processing finished."
<<
endl
;
}
void
ReductionController
::
startReduction
()
{
if
(
!
initApplication
())
{
return
;
}
// Send a simple message with the content of the Nexus data file.
string
fileContent
;
// Read the file.
readFile
(
fileDirectory
()
+
"/"
+
filename
(),
fileContent
);
// Request type.
madman
::
Request
type
;
// Set the type.
type
.
set_type
(
madman
::
Request
::
File
);
// Create the file request.
madman
::
FileRequest
request
;
request
.
set_content
(
fileContent
);
// Send the file content to the server.
m_requester
->
sendTwoBinaryParts
(
type
.
SerializeAsString
(),
request
.
SerializeAsString
());
// Wait for the response from the server.
string
response
;
m_requester
->
receive
(
response
);
}
}
src/controllers/mantidreduction/ReductionController.h
0 → 100644
View file @
732afa8f
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef MANTID_REDUCTIONCONTROLLER_H
#define MANTID_REDUCTIONCONTROLLER_H
#include <controllers/common/scanlegacy/GenericScan1D.h>
#include <cameo/cameo.h>
namespace
mantid
{
class
ReductionController
:
public
ExperimentController
{
public:
//! Type of controller
static
const
std
::
string
TYPE
;
ReductionController
(
const
std
::
string
&
name
);
ReductionController
(
const
ReductionController
&
controller
);
virtual
~
ReductionController
();
virtual
void
postConfiguration
();
void
startReduction
();
Property
<
std
::
string
>
serverEndpoint
;
Property
<
bool
>
initialized
;
Property
<
std
::
string
>
fileDirectory
;
Property
<
std
::
string
>
filename
;
ArrayProperty
<
float64
>
x
;
ArrayProperty
<
float64
>
data
;
private:
void
registerControllers
();
void
updateScanSerializerEvent
(
int32
i
);
bool
initApplication
();
void
readFile
(
const
std
::
string
&
nexusFileName
,
std
::
string
&
fileContent
);
void
writeFile
(
const
std
::
string
&
nexusFileName
,
const
std
::
string
&
fileContent
);
void
readProcessedFile
();
static
const
std
::
string
REMOTE_APPLICATION
;
static
const
std
::
string
RESPONDER
;
static
const
std
::
string
PUBLISHER
;
static
const
std
::
string
PROCESSED_FILE
;
std
::
unique_ptr
<
cameo
::
Server
>
m_server
;
std
::
unique_ptr
<
cameo
::
application
::
Instance
>
m_remoteApplication
;
std
::
unique_ptr
<
cameo
::
application
::
Requester
>
m_requester
;
std
::
unique_ptr
<
cameo
::
application
::
Subscriber
>
m_subscriber
;
std
::
unique_ptr
<
std
::
thread
>
m_subscriberThread
;
std
::
vector
<
scan
::
GenericScan1D
*>
m_scanControllers
;
};
}
#endif
src/controllers/mantidreduction/RequestMessages.proto
0 → 100644
View file @
732afa8f
package
madman
;
option
optimize_for
=
LITE_RUNTIME
;
message
Request
{
enum
Type
{
Reset
=
1
;
File
=
2
;
}
required
Type
type
=
1
;
}
message
FileRequest
{
required
bytes
content
=
1
;
}
message
EmptyRequest
{
}
message
Result
{
required
bytes
content
=
1
;
}
src/controllers/mantidreduction/gui/mantid_reductionPlotDatas.xml
0 → 100644
View file @
732afa8f
<plotdatas>
<plotdata
key=
"data"
color=
"1F96C0"
plugins=
"SETUP"
>
<dataX
p_role=
"mantid_reduction1"
p_name=
"x"
/>
<dataY
p_role=
"mantid_reduction1"
p_name=
"data"
/>
</plotdata>
</plotdatas>
src/controllers/mantidreduction/gui/mantid_reductionPlugin.xml
0 → 100644
View file @
732afa8f
<controller_plugin_config
type=
"mantid_reduction"
>
<image
key=
"ACQUISITION"
/>
<settings
view=
"mantid_reductionView.xml"
/>
<command
view=
"mantid_reductionCommandView.xml"
/>
</controller_plugin_config>
src/controllers/mantidreduction/gui/mantid_reductionProperties.xml
0 → 100644
View file @
732afa8f
<?xml version="1.0" encoding="ISO-8859-1" ?>
<controller
type=
"mantid_reduction"
>
<property
name=
"x"
type=
"doublearray"
>
</property>
<property
name=
"data"
type=
"doublearray"
>
</property>
</controller>
src/controllers/mantidreduction/gui/mantid_reductionView.xml
0 → 100644
View file @
732afa8f
<plugin>
<controller
type=
"mantid_reduction"
role=
"mantid_reduction1"
/>
<text
role=
"mantid_reduction1"
property=
"filename"
prefix=
"Filename"
/>
<newLine/>
<plot_launcher
role=
"mantid_reduction1"
data=
"data"
title=
"data"
height=
"20"
/>
</plugin>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment